aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2018-08-23 17:08:59 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2018-08-23 17:12:21 +0200
commit3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a (patch)
treeab49cc16ed0b853452c5c2ed2d3042416d628986 /thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries
downloadiot-sensors-master.tar.gz
iot-sensors-master.tar.bz2
iot-sensors-master.tar.xz
iot-sensors-master.zip
o Initial import.HEADmaster
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c447
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h274
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h343
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c189
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h424
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h577
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c160
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h183
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c399
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h351
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c210
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c757
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h172
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c65
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c392
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h139
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c1238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options3
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h213
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h132
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c855
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h345
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c222
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c237
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h302
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c745
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h58
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c394
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c436
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c265
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c370
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c637
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h307
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c172
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c254
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c317
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c247
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h112
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c3500
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h636
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h625
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c308
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c887
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h187
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c366
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c214
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c464
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h548
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c131
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h234
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c311
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c273
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c53
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c272
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h155
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c267
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c281
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c68
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c1213
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h227
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c384
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c531
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h519
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h169
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h240
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c196
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c230
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h303
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h105
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h67
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c168
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c149
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c458
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c114
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c169
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h136
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c319
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h481
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h112
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h218
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c1314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h999
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h229
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c471
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h252
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h268
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c225
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h226
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h145
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c430
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h285
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h189
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c662
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h344
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h359
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c633
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c578
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c365
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h291
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h226
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c739
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c1245
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h529
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c231
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h198
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c442
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c543
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c2164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h700
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h327
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c214
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h181
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h341
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c217
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c624
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c628
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h320
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h144
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h266
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c158
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c264
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h168
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c457
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c808
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c232
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h171
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c258
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h209
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c931
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c1009
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h338
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c465
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c547
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h429
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c288
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h211
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c298
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c1179
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h209
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c675
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h397
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c225
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h132
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h179
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c348
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h310
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h163
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h146
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h300
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c1075
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h313
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c278
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c568
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c330
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h304
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c366
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h342
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c160
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c1766
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h745
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h1094
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c1222
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h337
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h356
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h119
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h248
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c813
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h329
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h318
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h284
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h382
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c1190
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h362
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h268
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h208
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h360
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h138
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c508
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h515
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h281
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c506
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h186
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c557
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h309
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h174
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c620
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c2365
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h193
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h329
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c374
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h145
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h131
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h192
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h1204
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h449
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h279
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c54
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h199
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h86
435 files changed, 116134 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c
new file mode 100644
index 0000000..8d1609f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c
@@ -0,0 +1,447 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_atomic.h"
+
+#ifndef NRF_ATOMIC_USE_BUILD_IN
+#if (defined(__GNUC__) && defined(WIN32))
+ #define NRF_ATOMIC_USE_BUILD_IN 1
+#else
+ #define NRF_ATOMIC_USE_BUILD_IN 0
+#endif
+#endif // NRF_ATOMIC_USE_BUILD_IN
+
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U))
+#define STREX_LDREX_PRESENT
+#else
+#include "app_util_platform.h"
+#endif
+
+
+#if (NRF_ATOMIC_USE_BUILD_IN == 0) && defined(STREX_LDREX_PRESENT)
+#include "nrf_atomic_internal.h"
+#endif
+
+uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_exchange_n(p_data, value, __ATOMIC_SEQ_CST);
+
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+ NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
+
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data = value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ __atomic_store_n(p_data, value, __ATOMIC_SEQ_CST);
+ return value;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
+
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data = value;
+ CRITICAL_REGION_EXIT();
+ return value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_or(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data |= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_or_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data |= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_and(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data &= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_and_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data &= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_xor(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data ^= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_xor_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data ^= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_add(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data += value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_add_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data += value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_sub(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data -= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_sub_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data -= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t desired)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_compare_exchange(p_data,
+ p_expected,
+ &desired,
+ 1,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ return nrf_atomic_internal_cmp_exch(p_data, p_expected, desired);
+#else
+ CRITICAL_REGION_ENTER();
+ if(*p_data == *p_expected)
+ {
+ *p_data = desired;
+ return true;
+ }
+ else
+ {
+ *p_expected = *p_data;
+ return false;
+ }
+ CRITICAL_REGION_EXIT();
+#endif
+}
+
+uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ uint32_t expected = *p_data;
+ uint32_t new_val;
+ bool success;
+
+ do
+ {
+ if (expected >= value)
+ {
+ new_val = expected - value;
+ }
+ else
+ {
+ new_val = expected;
+ }
+ success = __atomic_compare_exchange(p_data,
+ &expected,
+ &new_val,
+ 1,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+ } while(!success);
+ return expected;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data -= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ uint32_t expected = *p_data;
+ uint32_t new_val;
+ bool success;
+
+ do
+ {
+ if (expected >= value)
+ {
+ new_val = expected - value;
+ }
+ else
+ {
+ new_val = expected;
+ }
+ success = __atomic_compare_exchange(p_data,
+ &expected,
+ &new_val,
+ 1,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+ } while(!success);
+ return new_val;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data -= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_fetch_or(p_data, 1);
+}
+
+uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_or(p_data, 1);
+}
+
+uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_fetch_and(p_data, 0);
+}
+
+uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_and(p_data, 0);
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h
new file mode 100644
index 0000000..6a11eee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h
@@ -0,0 +1,274 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_atomic Atomic operations API
+ * @ingroup app_common
+ * @{
+ *
+ * @brief @tagAPI52 This module implements C11 stdatomic.h simplified API.
+ At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions).
+ * Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t.
+ */
+
+#ifndef NRF_ATOMIC_H__
+#define NRF_ATOMIC_H__
+
+#include "sdk_common.h"
+
+/**
+ * @brief Atomic 32 bit unsigned type
+ * */
+typedef volatile uint32_t nrf_atomic_u32_t;
+
+/**
+ * @brief Atomic 1 bit flag type (technically 32 bit)
+ * */
+typedef volatile uint32_t nrf_atomic_flag_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Stores value to an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value to store
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Stores value to an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value to store
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical OR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand OR operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical OR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand OR operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical AND operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand AND operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical AND operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand AND operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical XOR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand XOR operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical XOR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand XOR operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic ADD operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand ADD operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic ADD operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand ADD operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief If value at pointer is equal to expected value, changes value at pointer to desired
+ *
+ * Atomically compares the value pointed to by p_data with the value pointed to by p_expected,
+ * and if those are equal, replaces the former with desired. Otherwise, loads the actual value
+ * pointed to by p_data into *p_expected.
+ *
+ * @param p_data Atomic memory pointer to test and modify.
+ * @param p_expected Pointer to test value.
+ * @param desired Value to be stored to atomic memory.
+ *
+ * @retval true *p_data was equal to *p_expected
+ * @retval false *p_data was not equal to *p_expected
+ */
+bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t desired);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object performed if object >= value.
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object performed if object >= value.
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**************************************************************************************************/
+
+/**
+ * @brief Logic one bit flag set operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return Old flag value
+ * */
+uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data);
+
+/**
+ * @brief Logic one bit flag set operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return New flag value
+ * */
+uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data);
+
+/**
+ * @brief Logic one bit flag clear operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return Old flag value
+ * */
+uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data);
+
+/**
+ * @brief Logic one bit flag clear operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return New flag value
+ * */
+uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h
new file mode 100644
index 0000000..534f1b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h
@@ -0,0 +1,343 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_ATOMIC_INTERNAL_H__
+#define NRF_ATOMIC_INTERNAL_H__
+
+#include "sdk_common.h"
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *
+ * @defgroup nrf_atomic_internal Atomic operations internals
+ * @ingroup nrf_atomic
+ * @{
+ *
+ */
+
+/* Only Cortex M cores > 3 support LDREX/STREX instructions*/
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
+#error "Unsupported core version"
+#endif
+
+#if defined ( __CC_ARM )
+static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ /* The base standard provides for passing arguments in core registers (r0-r3) and on the stack.
+ * Registers r4 and r5 have to be saved on stack. Note that only even number of register push are
+ * allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS].
+ * */
+ push {r4, r5}
+ mov r4, r0
+
+loop_mov
+ ldrex r0, [r4]
+ mov r5, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_mov
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+
+static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_orr
+ ldrex r0, [r4]
+ orr r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_orr
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_and
+ ldrex r0, [r4]
+ and r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_and
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_eor
+ ldrex r0, [r4]
+ eor r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_eor
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_add
+ ldrex r0, [r4]
+ add r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_add
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_sub
+ ldrex r0, [r4]
+ sub r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_sub
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t value)
+{
+#define RET_REG r0
+#define P_EXPC r1
+#define VALUE r2
+#define STR_RES r3
+#define P_DATA r4
+#define EXPC_VAL r5
+#define ACT_VAL r6
+
+ push {r4-r6}
+ mov P_DATA, r0
+ mov RET_REG, #0
+
+loop_cmp_exch
+ ldrex ACT_VAL, [P_DATA]
+ ldr EXPC_VAL, [P_EXPC]
+ cmp ACT_VAL, EXPC_VAL
+ ittee eq
+ strexeq STR_RES, VALUE, [P_DATA]
+ moveq RET_REG, #1
+ strexne STR_RES, ACT_VAL, [P_DATA]
+ strne ACT_VAL, [P_EXPC]
+ cmp STR_RES, #0
+ itt ne
+ movne RET_REG, #0
+ bne loop_cmp_exch
+
+ pop {r4-r6}
+ bx lr
+
+#undef RET_REG
+#undef P_EXPC
+#undef VALUE
+#undef STR_RES
+#undef P_DATA
+#undef EXPC_VAL
+#undef ACT_VAL
+}
+
+static __asm uint32_t nrf_atomic_internal_sub_hs(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_sub_ge
+ ldrex r0, [r4]
+ cmp r0, r1
+ ite hs
+ subhs r5, r0, r1
+ movlo r5, r0
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_sub_ge
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+
+#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
+ old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val)
+
+#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
+
+/**
+ * @brief Atomic operation generic macro
+ * @param[in] asm_op operation: mov, orr, and, eor, add, sub
+ * @param[out] old_val atomic object output (uint32_t), value before operation
+ * @param[out] new_val atomic object output (uint32_t), value after operation
+ * @param[in] value atomic operation operand
+ * */
+#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
+{ \
+ uint32_t str_res; \
+ __ASM volatile( \
+ "1: ldrex %["#old_val"], [%["#ptr"]]\n" \
+ NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \
+ " strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \
+ " teq %[str_res], #0\n" \
+ " bne.n 1b" \
+ : \
+ [old_val]"=&r" (old_val), \
+ [new_val]"=&r" (new_val), \
+ [str_res]"=&r" (str_res) \
+ : \
+ [ptr]"r" (ptr), \
+ [value]"r" (value) \
+ : "cc"); \
+ UNUSED_PARAMETER(str_res); \
+}
+
+#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_sub_hs(new_val, old_val, value) \
+ "cmp %["#old_val"], %["#value"]\n " \
+ "ite hs\n" \
+ "subhs %["#new_val"], %["#old_val"], %["#value"]\n" \
+ "movlo %["#new_val"], %["#old_val"]\n"
+
+static inline bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t value)
+{
+ bool res = false;
+ uint32_t str_res = 0;
+ uint32_t act_val = 0;
+ uint32_t exp_val = 0;
+ UNUSED_VARIABLE(str_res);
+ UNUSED_VARIABLE(act_val);
+ UNUSED_VARIABLE(exp_val);
+ __ASM volatile(
+ "1: ldrex %[act_val], [%[ptr]]\n"
+ " ldr %[exp_val], [%[expc]]\n"
+ " cmp %[act_val], %[exp_val]\n"
+ " ittee eq\n"
+ " strexeq %[str_res], %[value], [%[ptr]]\n"
+ " moveq %[res], #1\n"
+ " strexne %[str_res], %[act_val], [%[ptr]]\n"
+ " strne %[act_val], [%[expc]]\n"
+ " cmp %[str_res], #0\n"
+ " itt ne\n"
+ " movne %[res], #0\n"
+ " bne.n 1b"
+ :
+ [res] "=&r" (res),
+ [exp_val] "=&r" (exp_val),
+ [act_val] "=&r" (act_val),
+ [str_res] "=&r" (str_res)
+ :
+ "0" (res),
+ "1" (exp_val),
+ "2" (act_val),
+ [expc] "r" (p_expected),
+ [ptr] "r" (p_data),
+ [value] "r" (value)
+ : "cc");
+ return res;
+}
+
+#else
+#error "Unsupported compiler"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_INTERNAL_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h
new file mode 100644
index 0000000..bbc302c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_ATOMIC_SANITY_CHECK_H__
+#define NRF_ATOMIC_SANITY_CHECK_H__
+
+#include "nrf_atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Quick sanity check of nrf_atomic API
+ * */
+static inline void nrf_atomic_sanity_check(void)
+{
+#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+ nrf_atomic_u32_t val;
+ nrf_atomic_u32_t flag;
+
+ /*Fetch version tests*/
+ val = 0;
+ ASSERT(nrf_atomic_u32_store_fetch(&val, 10) == 0);
+ ASSERT(nrf_atomic_u32_store_fetch(&val, 0) == 10);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 16) == 0);
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == (0xFFFFFFFF));
+
+ val = 0xFFFFFFFF;
+ ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 16)) == 0xFFFFFFFF);
+ ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 5)) == (0xFFFFFFFF & ~((1 << 16))));
+ ASSERT(nrf_atomic_u32_and_fetch(&val, 0) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5)))));
+ ASSERT(nrf_atomic_u32_and_fetch(&val, 0xFFFFFFFF) == (0));
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16)) == 0);
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 5)) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16) | (1 << 5)) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == (0));
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 0);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 100);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 1 << 24) == 200);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0xFFFFFFFF) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 - 1 + (1 << 24)));
+
+ val = 1000;
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 1000);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 900);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 800);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0xFFFFFFFF) == 800);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 801);
+
+ flag = 0;
+ ASSERT(nrf_atomic_flag_set_fetch(&flag) == 0);
+ ASSERT(nrf_atomic_flag_set_fetch(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 0);
+
+ /*No fetch version tests*/
+ val = 0;
+ ASSERT(nrf_atomic_u32_store(&val, 10) == 10);
+ ASSERT(nrf_atomic_u32_store(&val, 0) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 16) == 1 << 16);
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 0xFFFFFFFF) == 0xFFFFFFFF);
+
+ val = 0xFFFFFFFF;
+ ASSERT(nrf_atomic_u32_and(&val, ~(1 << 16)) == (0xFFFFFFFF & ~((1 << 16))));
+ ASSERT(nrf_atomic_u32_and(&val, ~(1 << 5)) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5)))));
+ ASSERT(nrf_atomic_u32_and(&val, 0) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 16)) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 5)) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 16) | (1 << 5)) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_add(&val, 100) == 100);
+ ASSERT(nrf_atomic_u32_add(&val, 100) == 200);
+ ASSERT(nrf_atomic_u32_add(&val, 1 << 24) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add(&val, 0) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add(&val, 0xFFFFFFFF) == (200 - 1 + (1 << 24)));
+
+ val = 1000;
+ ASSERT(nrf_atomic_u32_sub(&val, 100) == 900);
+ ASSERT(nrf_atomic_u32_sub(&val, 100) == 800);
+ ASSERT(nrf_atomic_u32_sub(&val, 0) == 800);
+ ASSERT(nrf_atomic_u32_sub(&val, 0xFFFFFFFF) == 801);
+
+ flag = 0;
+ ASSERT(nrf_atomic_flag_set(&flag) == 1);
+ ASSERT(nrf_atomic_flag_set(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear(&flag) == 0);
+ ASSERT(nrf_atomic_flag_clear(&flag) == 0);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_SANITY_CHECK_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c
new file mode 100644
index 0000000..5d7a8ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "nrf_atfifo.h"
+#include "nrf_atfifo_internal.h"
+
+#if NRF_ATFIFO_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_ATFIFO_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INIT_FILTER_LEVEL NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_ATFIFO_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_ATFIFO_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_ATFIFO_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+
+/* Unions testing */
+STATIC_ASSERT(sizeof(nrf_atfifo_postag_t) == sizeof(uint32_t));
+
+
+ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size)
+{
+ if (NULL == p_buf)
+ {
+ NRF_LOG_INST_ERROR(p_fifo->p_log, "Initialization failed. p_buf == NULL");
+ return NRF_ERROR_NULL;
+ }
+ if (0 != (buf_size % item_size))
+ {
+ NRF_LOG_INST_ERROR(p_fifo->p_log, "Initialization failed. Buf_size not multiple of item_size");
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_fifo->p_buf = p_buf;
+ p_fifo->tail.tag = 0;
+ p_fifo->head.tag = 0;
+ p_fifo->buf_size = buf_size;
+ p_fifo->item_size = item_size;
+
+ NRF_LOG_INST_INFO(p_fifo->p_log, "Initialized.");
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo)
+{
+ bool released = nrf_atfifo_space_clear(p_fifo);
+ NRF_LOG_INST_INFO(p_fifo->p_log, "Cleared result:%s", released ? "success" : "busy");
+ return released ? NRF_SUCCESS : NRF_ERROR_BUSY;
+}
+
+
+ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * p_var, size_t size, bool * const p_visible)
+{
+ nrf_atfifo_item_put_t context;
+ bool visible;
+ void * p_data = nrf_atfifo_item_alloc(p_fifo, &context);
+ if (NULL == p_data)
+ {
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Copying in element (0x%08X) failed - no space.", p_var);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memcpy(p_data, p_var, size);
+
+ visible = nrf_atfifo_item_put(p_fifo, &context);
+ if (NULL != p_visible)
+ {
+ *p_visible = visible;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Element (0x%08X) copied in.", p_var);
+ return NRF_SUCCESS;
+}
+
+
+void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context)
+{
+ if (nrf_atfifo_wspace_req(p_fifo, &(p_context->last_tail)))
+ {
+ void * p_item = ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr;
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Allocated element (0x%08X).", p_item);
+ return p_item;
+ }
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Allocation failed - no space.");
+ return NULL;
+}
+
+
+bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context)
+{
+ if ((p_context->last_tail.pos.wr) == (p_context->last_tail.pos.rd))
+ {
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Put (uninterrupted)");
+ nrf_atfifo_wspace_close(p_fifo);
+ return true;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Put (interrupted!)");
+ return false;
+}
+
+
+ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released)
+{
+ nrf_atfifo_item_get_t context;
+ bool released;
+ void const * p_s = nrf_atfifo_item_get(p_fifo, &context);
+ if (NULL == p_s)
+ {
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Copying out failed - no item in the FIFO.");
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ memcpy(p_var, p_s, size);
+
+ released = nrf_atfifo_item_free(p_fifo, &context);
+ if (NULL != p_released)
+ {
+ *p_released = released;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Element (0x%08X) copied out.", p_var);
+ return NRF_SUCCESS;
+}
+
+
+void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
+{
+ if (nrf_atfifo_rspace_req(p_fifo, &(p_context->last_head)))
+ {
+ void * p_item = ((uint8_t*)(p_fifo->p_buf)) + p_context->last_head.pos.rd;
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Get element: 0x%08X", p_item);
+ return p_item;
+ }
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Get failed - no item in the FIFO.");
+ return NULL;
+}
+
+
+bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
+{
+ if ((p_context->last_head.pos.wr) == (p_context->last_head.pos.rd))
+ {
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Free (uninterrupted)");
+ nrf_atfifo_rspace_close(p_fifo);
+ return true;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Free (interrupted)");
+ return false;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h
new file mode 100644
index 0000000..37cfc76
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h
@@ -0,0 +1,424 @@
+/**
+ * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_ATFIFO_H__
+#define NRF_ATFIFO_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_assert.h"
+#include "sdk_errors.h"
+#include "nrf_log_instance.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_atfifo Atomic FIFO
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52 FIFO implementation that allows for making atomic transactions without
+ * locking interrupts.
+ *
+ * @details There are two types of functions to prepare the FIFO writing:
+ * - Single function for simple access:
+ * @code
+ * if (NRF_SUCCESS != nrf_atfifo_simple_put(my_fifo, &data, NULL))
+ * {
+ * // Error handling
+ * }
+ * @endcode
+ * - Function pair to limit data copying:
+ * @code
+ * struct point3d
+ * {
+ * int x, y, z;
+ * }point3d_t;
+ * nrf_atfifo_context_t context;
+ * point3d_t * point;
+ *
+ * if (NULL != (point = nrf_atfifo_item_alloc(my_fifo, &context)))
+ * {
+ * point->x = a;
+ * point->y = b;
+ * point->z = c;
+ * if (nrf_atfifo_item_put(my_fifo, &context))
+ * {
+ * // Send information to the rest of the system
+ * // that there is new data in the FIFO available for reading.
+ * }
+ * }
+ * else
+ * {
+ * // Error handling
+ * }
+ *
+ * @endcode
+ * @note
+ * This atomic FIFO implementation requires that the operation that is
+ * opened last is finished (committed/flushed) first.
+ * This is typical for operations performed from the interrupt runtime
+ * when the other operation is performed from the main thread.
+ *
+ * This implementation does not support typical multithreading operating system
+ * access where operations can be started and finished in totally unrelated order.
+ *
+ * @{
+ */
+
+/**
+ * @brief Read and write position structure.
+ *
+ * A structure that holds the read and write position used by the FIFO head and tail.
+ */
+typedef struct nrf_atfifo_postag_pos_s
+{
+ uint16_t wr; //!< First free space to write the data
+ uint16_t rd; //!< A place after the last data to read
+}nrf_atfifo_postag_pos_t;
+
+/**
+ * @brief End data index tag.
+ *
+ * A tag used to mark the end of data.
+ * To properly realize atomic data committing, the whole variable has to be
+ * accessed atomically.
+ */
+typedef union nrf_atfifo_postag_u
+{
+ uint32_t tag; //!< Whole tag, used for atomic, 32-bit access
+ nrf_atfifo_postag_pos_t pos; //!< Structure that holds reading and writing position separately
+}nrf_atfifo_postag_t;
+
+/**
+ * @brief The FIFO instance.
+ *
+ * The instance of atomic FIFO.
+ * Used with all FIFO functions.
+ */
+typedef struct nrf_atfifo_s
+{
+ void * p_buf; //!< Pointer to the data buffer
+ nrf_atfifo_postag_t tail; //!< Read and write tail position tag
+ nrf_atfifo_postag_t head; //!< Read and write head position tag
+ uint16_t buf_size; //!< FIFO size in number of bytes (has to be divisible by @c item_size)
+ uint16_t item_size; //!< Size of a single FIFO item
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
+}nrf_atfifo_t;
+
+/**
+ * @brief FIFO write operation item context.
+ *
+ * Context structure used to mark an allocated space in FIFO that is ready for put.
+ * All the data required to properly put allocated and written data.
+ */
+typedef struct nrf_atfifo_item_put_s
+{
+ nrf_atfifo_postag_t last_tail; //!< Tail tag value that was here when opening the FIFO to write
+}nrf_atfifo_item_put_t;
+
+
+/**
+ * @brief FIFO read operation item context.
+ *
+ * Context structure used to mark an opened get operation to properly free an item after reading.
+ */
+typedef struct nrf_atfifo_rcontext_s
+{
+ nrf_atfifo_postag_t last_head; //!< Head tag value that was here when opening the FIFO to read
+}nrf_atfifo_item_get_t;
+
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define NRF_ATFIFO_LOG_NAME atfifo
+
+/**
+ * @defgroup nrf_atfifo_instmacros FIFO instance macros
+ *
+ * A group of macros helpful for FIFO instance creation and initialization.
+ * They may be used to create and initialize instances for most use cases.
+ *
+ * FIFO may also be created and initialized directly using
+ * @ref nrf_atfifo_init function.
+ * @{
+ */
+ /**
+ * @brief Macro for generating the name for a data buffer.
+ *
+ * The name of the data buffer that would be created by
+ * @ref NRF_ATFIFO_DEF macro.
+ *
+ * @param[in] fifo_id Identifier of the FIFO object.
+ *
+ * @return Name of the buffer variable.
+ *
+ * @note This is auxiliary internal macro and in normal usage
+ * it should not be called.
+ */
+ #define NRF_ATFIFO_BUF_NAME(fifo_id) CONCAT_2(fifo_id, _data)
+
+ /**
+ * @brief Macro for generating the name for a FIFO instance.
+ *
+ * The name of the instance variable that will be created by the
+ * @ref NRF_ATFIFO_DEF macro.
+ *
+ * @param[in] fifo_id Identifier of the FIFO object.
+ *
+ * @return Name of the instance variable.
+ *
+ * @note This is auxiliary internal macro and in normal usage
+ * it should not be called.
+ */
+ #define NRF_ATFIFO_INST_NAME(fifo_id) CONCAT_2(fifo_id, _inst)
+
+ /**
+ * @brief Macro for creating an instance.
+ *
+ * Creates the FIFO object variable itself.
+ *
+ * Usage example:
+ * @code
+ * NRF_ATFIFO_DEF(my_fifo, uint16_t, 12);
+ * NRF_ATFIFO_INIT(my_fifo);
+ *
+ * uint16_t some_val = 45;
+ * nrf_atfifo_item_put(my_fifo, &some_val, sizeof(some_val), NULL);
+ * nrf_atfifo_item_get(my_fifo, &some_val, sizeof(some_val), NULL);
+ * @endcode
+ *
+ * @param[in] fifo_id Identifier of a FIFO object.
+ * This identifier will be a pointer to the instance.
+ * It makes it possible to use this directly for the functions
+ * that operate on the FIFO.
+ * Because it is a static const object, it should be optimized by the compiler.
+ * @param[in] storage_type Type of data that will be stored in the FIFO.
+ * @param[in] item_cnt Capacity of the created FIFO in maximum number of items that may be stored.
+ * The phisical size of the buffer will be 1 element bigger.
+ */
+ #define NRF_ATFIFO_DEF(fifo_id, storage_type, item_cnt) \
+ static storage_type NRF_ATFIFO_BUF_NAME(fifo_id)[(item_cnt)+1]; \
+ NRF_LOG_INSTANCE_REGISTER(NRF_ATFIFO_LOG_NAME, fifo_id, \
+ NRF_ATFIFO_CONFIG_INFO_COLOR, \
+ NRF_ATFIFO_CONFIG_DEBUG_COLOR, \
+ NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL, \
+ NRF_ATFIFO_CONFIG_LOG_ENABLED ? \
+ NRF_ATFIFO_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ static nrf_atfifo_t NRF_ATFIFO_INST_NAME(fifo_id) = { \
+ .p_buf = NULL, \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_ATFIFO_LOG_NAME, fifo_id) \
+ }; \
+ static nrf_atfifo_t * const fifo_id = &NRF_ATFIFO_INST_NAME(fifo_id)
+
+ /**
+ * @brief Macro for initializing the FIFO that was previously declared by the macro.
+ *
+ * Use this macro to simplify FIFO initialization.
+ *
+ * @note
+ * This macro can be only used on a FIFO object defined by @ref NRF_ATFIFO_DEF macro.
+ *
+ * @param[in] fifo_id Identifier of the FIFO object.
+ *
+ * @return Value from the @ref nrf_atfifo_init function.
+ */
+ #define NRF_ATFIFO_INIT(fifo_id) \
+ nrf_atfifo_init( \
+ fifo_id, \
+ NRF_ATFIFO_BUF_NAME(fifo_id), \
+ sizeof(NRF_ATFIFO_BUF_NAME(fifo_id)), \
+ sizeof(NRF_ATFIFO_BUF_NAME(fifo_id)[0]) \
+ )
+
+/** @} */
+
+/**
+ * @brief Function for initializing the FIFO.
+ *
+ * Preparing the FIFO instance to work.
+ *
+ * @param[out] p_fifo FIFO object to initialize.
+ * @param[in,out] p_buf FIFO buffer for storing data.
+ * @param[in] buf_size Total buffer size (has to be divisible by @c item_size).
+ * @param[in] item_size Size of a single item held inside the FIFO.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If a NULL pointer is provided as the buffer.
+ * @retval NRF_ERROR_INVALID_LENGTH If size of the buffer provided is not divisible by @c item_size.
+ *
+ * @note
+ * Buffer size must be able to hold one element more than the designed FIFO capacity.
+ * This one, empty element is used for overflow checking.
+ */
+ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size);
+
+/**
+ * @brief Function for clearing the FIFO.
+ *
+ * Function for clearing the FIFO.
+ *
+ * If this function is called during an opened and uncommitted write operation,
+ * the FIFO is cleared up to the currently ongoing commit.
+ * There is no possibility to cancel an ongoing commit.
+ *
+ * If this function is called during an opened and unflushed read operation,
+ * the read position in the head is set, but copying it into the write head position
+ * is left to read closing operation.
+ *
+ * This way, there is no more data to read, but the memory is released
+ * in the moment when it is safe.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @retval NRF_SUCCESS FIFO totally cleared.
+ * @retval NRF_ERROR_BUSY Function called in the middle of writing or reading operation.
+ * If it is called in the middle of writing operation,
+ * FIFO was cleared up to the already started and uncommitted write.
+ * If it is called in the middle of reading operation,
+ * write head was only moved. It will be copied into read tail when the reading operation
+ * is flushed.
+ */
+ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo);
+
+/**
+ * @brief Function for atomically putting data into the FIFO.
+ *
+ * It uses memcpy function inside and in most situations, it is more suitable to
+ * use @ref nrf_atfifo_item_alloc, write the data, and @ref nrf_atfifo_item_put to store a new value
+ * in a FIFO.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[in] p_var Variable to copy.
+ * @param[in] size Size of the variable to copy.
+ * Can be smaller or equal to the FIFO item size.
+ * @param[out] p_visible See value returned by @ref nrf_atfifo_item_put.
+ * It may be NULL if the caller does not require the current operation status.
+ *
+ * @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
+ * @retval NRF_ERROR_NO_MEM If the FIFO is full.
+ *
+ * @note
+ * To avoid data copying, you can use the @ref nrf_atfifo_item_alloc and @ref nrf_atfifo_item_put
+ * functions pair.
+ */
+ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * const p_var, size_t size, bool * const p_visible);
+
+/**
+ * @brief Function for opening the FIFO for writing.
+ *
+ * Function called to start the FIFO write operation and access the given FIFO buffer directly.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] p_context Operation context, required by @ref nrf_atfifo_item_put.
+ *
+ * @return Pointer to the space where variable data can be stored.
+ * NULL if there is no space in the buffer.
+ */
+void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context);
+
+/**
+ * @brief Function for closing the writing operation.
+ *
+ * Puts a previously allocated context into FIFO.
+ * This function must be called to commit an opened write operation.
+ * It sets all the buffers and marks the data, so that it is visible to read.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[in] p_context Operation context, filled by the @ref nrf_atfifo_item_alloc function.
+ *
+ * @retval true Data is currently ready and will be visible to read.
+ * @retval false The internal commit was marked, but the writing operation interrupted another writing operation.
+ * The data will be available to read when the interrupted operation is committed.
+ */
+bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context);
+
+/**
+ * @brief Function for getting a single value from the FIFO.
+ *
+ * This function gets the value from the top of the FIFO.
+ * The value is removed from the FIFO memory.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] p_var Pointer to the variable to store the data.
+ * @param[in] size Size of the data to be loaded.
+ * @param[out] p_released See the values returned by @ref nrf_atfifo_item_free.
+ *
+ * @retval NRF_SUCCESS Element was successfully copied from the FIFO memory.
+ * @retval NRF_ERROR_NOT_FOUND No data in the FIFO.
+ */
+ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released);
+
+/**
+ * @brief Function for opening the FIFO for reading.
+ *
+ * Function called to start the FIFO read operation and access the given FIFO buffer directly.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] p_context The operation context, required by @ref nrf_atfifo_item_free
+ *
+ * @return Pointer to data buffer or NULL if there is no data in the FIFO.
+ */
+void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
+
+/**
+ * @brief Function for closing the reading operation.
+ *
+ * Function used to finish the reading operation.
+ * If this reading operation does not interrupt another reading operation, the head write buffer is moved.
+ * If this reading operation is placed in the middle of another reading, only the new read pointer is written.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[in] p_context Context of the reading operation to be closed.
+ *
+ * @retval true This operation is not generated in the middle of another read operation and the write head will be updated to the read head (space is released).
+ * @retval false This operation was performed in the middle of another read operation and the write buffer head was not moved (no space is released).
+ */
+bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATFIFO_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h
new file mode 100644
index 0000000..e38a223
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h
@@ -0,0 +1,577 @@
+/**
+ * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief Atomic FIFO internal file
+ *
+ * This file should be included only by nrf_atfifo internally.
+ * Needs nrf_atfifo.h included first.
+ */
+#ifndef NRF_ATFIFO_H__
+#error This is internal file. Do not include this file in your program.
+#endif
+
+#ifndef NRF_ATFIFO_INTERNAL_H__
+#define NRF_ATFIFO_INTERNAL_H__
+#include <stddef.h>
+#include "nrf.h"
+#include "app_util.h"
+#include "nordic_common.h"
+
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
+#error Unsupported core version
+#endif
+
+/*
+ * Make sure that rd and wr pos in a tag are aligned like expected
+ * Changing this would require changes inside assembly code!
+ */
+STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, wr) == 0);
+STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, rd) == 2);
+
+/**
+ * @brief Atomically reserve space for a new write.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] old_tail Tail position tag before new space is reserved.
+ *
+ * @retval true Space available.
+ * @retval false Memory full.
+ *
+ * @sa nrf_atfifo_wspace_close
+ */
+static bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail);
+
+/**
+ * @brief Atomically mark all written data available.
+ *
+ * This function marks all data available for reading.
+ * This marking is done by copying tail.pos.wr into tail.pos.rd.
+ *
+ * It must be called only when closing the first write.
+ * It cannot be called if any write access was interrupted.
+ * See the code below:
+ * @code
+ * if (old_tail.pos.wr == old_tail.pos.rd)
+ * {
+ * nrf_atfifo_wspace_close(my_fifo);
+ * return true;
+ * }
+ * return false;
+ * @endcode
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @sa nrf_atfifo_wspace_req
+ */
+static void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo);
+
+/**
+ * @brief Atomically get a part of a buffer to read data.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] old_head Head position tag before the data buffer is read.
+ *
+ * @retval true Data available for reading.
+ * @retval false No data in the buffer.
+ *
+ * @sa nrf_atfifo_rspace_close
+ */
+static bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head);
+
+/**
+ * @brief Atomically release all read data.
+ *
+ * This function marks all data that was read as free space,
+ * which is available for writing.
+ * This marking is done by copying head.pos.rd into head.pos.wr.
+ *
+ * It must be called only when closing the first read.
+ * It cannot be called when the current read access interrupted any other read access.
+ * See code below:
+ * @code
+ * if (old_head.pos.wr == old_head.pos.rd)
+ * {
+ * nrf_atfifo_rspace_close(my_fifo);
+ * return true;
+ * }
+ * return false;
+ * @endcode
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @sa nrf_atfifo_rspace_req
+ */
+static void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo);
+
+/**
+ * @brief Safely clear the FIFO, internal function.
+ *
+ * This function realizes the functionality required by @ref nrf_atfifo_clear.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @retval true All the data was released.
+ * @retval false All the data available for releasing was released, but there is some pending transfer.
+ */
+static bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo);
+
+
+/* ---------------------------------------------------------------------------
+ * Implementation starts here
+ */
+
+#if defined ( __CC_ARM )
+
+
+__ASM bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - p_old_tail
+ * R2 - internal variable old_tail (saved by caller)
+ * R3 - internal variable new_tail (saved by caller)
+ * R4 - internal temporary register (saved by this function)
+ * R5 - not used stored to keep the stack aligned to 8 bytes
+ * Returned value:
+ * R0 (bool - 32 bits)
+ */
+ push {r4, r5}
+nrf_atfifo_wspace_req_repeat
+ /* Load tail tag and set memory monitor !!! R2 - old tail !!! */
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ /* Extract write position !!! R3 !!! */
+ uxth r3, r2
+ /* Increment address with overload support !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, item_size))]
+ add r3, r4
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, buf_size))]
+ cmp r3, r4
+ it hs
+ subhs r3, r3, r4
+
+ /* Check if FIFO would overload after making this increment !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr))]
+ cmp r3, r4
+ ittt eq
+ clrexeq
+ moveq r0, #__cpp(false)
+ beq nrf_atfifo_wspace_req_exit
+
+ /* Pack everything back !!! R3 - new tail !!! */
+ /* Copy lower byte from new_tail, and higher byte is a value from the top of old_tail */
+ pkhbt r3, r3, r2
+
+ /* Store new value clearing memory monitor !!! R4 used temporary !!! */
+ strex r4, r3, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ cmp r4, #0
+ bne nrf_atfifo_wspace_req_repeat
+
+ /* Return true */
+ mov r0, #__cpp(true)
+nrf_atfifo_wspace_req_exit
+ /* Save old tail */
+ str r2, [r1]
+ pop {r4, r5}
+ bx lr
+}
+
+
+__ASM void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - internal temporary register
+ * R2 - new_tail
+ */
+nrf_atfifo_wspace_close_repeat
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ /* Copy from lower byte to higher */
+ pkhbt r2, r2, r2, lsl #16
+
+ strex r1, r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ cmp r1, #0
+ bne nrf_atfifo_wspace_close_repeat
+ bx lr
+}
+
+
+__ASM bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - p_old_head
+ * R2 - internal variable old_head (saved by caller)
+ * R3 - internal variable new_head (saved by caller)
+ * R4 - internal temporary register (saved by this function)
+ * R5 - not used stored to keep the stack aligned to 8 bytes
+ * Returned value:
+ * R0 (bool - 32 bits)
+ */
+ push {r4, r5}
+nrf_atfifo_rspace_req_repeat
+ /* Load tail tag and set memory monitor !!! R2 - old tail !!! */
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ /* Extract read position !!! R3 !!! */
+ uxth r3, r2, ror #16
+
+ /* Check if we have any data !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))]
+ cmp r3, r4
+ ittt eq
+ clrexeq
+ moveq r0, #__cpp(false)
+ beq nrf_atfifo_rspace_req_exit
+
+ /* Increment address with overload support !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, item_size))]
+ add r3, r4
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, buf_size))]
+ cmp r3, r4
+ it hs
+ subhs r3, r3, r4
+
+ /* Pack everything back !!! R3 - new tail !!! */
+ /* Copy lower byte from old_head, and higher byte is a value from write_pos */
+ pkhbt r3, r2, r3, lsl #16
+
+ /* Store new value clearing memory monitor !!! R4 used temporary !!! */
+ strex r4, r3, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ cmp r4, #0
+ bne nrf_atfifo_rspace_req_repeat
+
+ /* Return true */
+ mov r0, #__cpp(true)
+nrf_atfifo_rspace_req_exit
+ /* Save old head */
+ str r2, [r1]
+ pop {r4, r5}
+ bx lr
+}
+
+
+__ASM void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - internal temporary register
+ * R2 - new_tail
+ */
+nrf_atfifo_rspace_close_repeat
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ /* Copy from higher byte to lower */
+ pkhtb r2, r2, r2, asr #16
+
+ strex r1, r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ cmp r1, #0
+ bne nrf_atfifo_rspace_close_repeat
+ bx lr
+}
+
+
+__ASM bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo)
+{
+ /* Registry usage:
+ * R0 - p_fifo as input, bool output after
+ * R1 - tail, rd pointer, new_head
+ * R2 - head_old, destroyed when creating new_head
+ * R3 - p_fifo - copy
+ */
+ mov r3, r0
+nrf_atfifo_space_clear_repeat
+ /* Load old head in !!! R2 register !!! and read pointer of tail in !!! R1 register !!! */
+ ldrex r2, [r3, #__cpp(offsetof(nrf_atfifo_t, head))]
+ ldrh r1, [r3, #__cpp(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))]
+ cmp r2, r2, ror #16
+ /* Return false as default */
+ mov r0, #__cpp(false)
+ /* Create new head in !!! R1 register !!! Data in !!! R2 register broken !!! */
+ itett ne
+ uxthne r2, r2
+ orreq r1, r1, r1, lsl #16
+ orrne r1, r2, r1, lsl #16
+
+ /* Skip header test */
+ bne nrf_atfifo_space_clear_head_test_skip
+
+ /* Load whole tail and test it !!! R2 used !!! */
+ ldr r2, [r3, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ cmp r2, r2, ror #16
+ /* Return true if equal */
+ it eq
+ moveq r0, #__cpp(true)
+
+nrf_atfifo_space_clear_head_test_skip
+ /* Store and test if success !!! R2 used temporary !!! */
+ strex r2, r1, [r3, #__cpp(offsetof(nrf_atfifo_t, head))]
+ cmp r2, #0
+ bne nrf_atfifo_space_clear_repeat
+ bx lr
+}
+
+#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
+
+bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
+{
+ volatile bool ret;
+ volatile uint32_t old_tail;
+ uint32_t new_tail;
+ uint32_t temp;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[old_tail], [%[p_fifo], %[offset_tail]] \n"
+ " uxth %[new_tail], %[old_tail] \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
+ " add %[new_tail], %[temp] \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
+ " cmp %[new_tail], %[temp] \n"
+ " it hs \n"
+ " subhs %[new_tail], %[new_tail], %[temp] \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n"
+ " cmp %[new_tail], %[temp] \n"
+ " ittt eq \n"
+ " clrexeq \n"
+ " moveq %[ret], %[false_val] \n"
+ " beq.n 2f \n"
+ " \n"
+ " pkhbt %[new_tail], %[new_tail], %[old_tail] \n"
+ " \n"
+ " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ " \n"
+ " mov %[ret], %[true_val] \n"
+ "2: \n"
+ : /* Output operands */
+ [ret] "=r"(ret),
+ [temp] "=&r"(temp),
+ [old_tail]"=&r"(old_tail),
+ [new_tail]"=&r"(new_tail)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
+ [offset_head_wr] "J"(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)),
+ [offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
+ [offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
+ [true_val] "I"(true),
+ [false_val] "I"(false)
+ : /* Clobbers */
+ "cc");
+
+ p_old_tail->tag = old_tail;
+ UNUSED_VARIABLE(new_tail);
+ UNUSED_VARIABLE(temp);
+ return ret;
+}
+
+
+void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo)
+{
+ uint32_t temp;
+ uint32_t new_tail;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[new_tail], [%[p_fifo], %[offset_tail]] \n"
+ " pkhbt %[new_tail],%[new_tail], %[new_tail], lsl #16 \n"
+ " \n"
+ " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ : /* Output operands */
+ [temp] "=&r"(temp),
+ [new_tail] "=&r"(new_tail)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_tail] "J"(offsetof(nrf_atfifo_t, tail))
+ : /* Clobbers */
+ "cc");
+
+ UNUSED_VARIABLE(temp);
+ UNUSED_VARIABLE(new_tail);
+}
+
+
+bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head)
+{
+ volatile bool ret;
+ volatile uint32_t old_head;
+ uint32_t new_head;
+ uint32_t temp;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n"
+ " uxth %[new_head], %[old_head], ror #16 \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_tail_rd]] \n"
+ " cmp %[new_head], %[temp] \n"
+ " ittt eq \n"
+ " clrexeq \n"
+ " moveq %[ret], %[false_val] \n"
+ " beq.n 2f \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
+ " add %[new_head], %[temp] \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
+ " cmp %[new_head], %[temp] \n"
+ " it hs \n"
+ " subhs %[new_head], %[new_head], %[temp] \n"
+ " \n"
+ " pkhbt %[new_head], %[old_head], %[new_head], lsl #16 \n"
+ " \n"
+ " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ " \n"
+ " mov %[ret], %[true_val] \n"
+ "2: \n"
+ : /* Output operands */
+ [ret] "=r"(ret),
+ [temp] "=&r"(temp),
+ [old_head]"=&r"(old_head),
+ [new_head]"=&r"(new_head)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_head] "J"(offsetof(nrf_atfifo_t, head)),
+ [offset_tail_rd] "J"(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)),
+ [offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
+ [offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
+ [true_val] "I"(true),
+ [false_val] "I"(false)
+ : /* Clobbers */
+ "cc");
+
+ p_old_head->tag = old_head;
+ UNUSED_VARIABLE(new_head);
+ UNUSED_VARIABLE(temp);
+ return ret;
+}
+
+
+void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo)
+{
+ uint32_t temp;
+ uint32_t new_head;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " pkhtb %[new_head],%[new_head], %[new_head], asr #16 \n"
+ " \n"
+ " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ : /* Output operands */
+ [temp] "=&r"(temp),
+ [new_head] "=&r"(new_head)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_head] "J"(offsetof(nrf_atfifo_t, head))
+ : /* Clobbers */
+ "cc");
+
+ UNUSED_VARIABLE(temp);
+ UNUSED_VARIABLE(new_head);
+}
+
+
+bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo)
+{
+ volatile bool ret;
+ uint32_t old_head; /* This variable is left broken after assembly code finishes */
+ uint32_t new_head;
+
+ __ASM volatile(
+ "1: \n"
+ " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n"
+ " ldrh %[new_head], [%[p_fifo], %[offset_tail_rd]] \n"
+ " cmp %[old_head], %[old_head], ror #16 \n"
+ " \n"
+ " mov %[ret], %[false_val] \n"
+ " \n"
+ " itett ne \n"
+ " uxthne %[old_head], %[old_head] \n"
+ " orreq %[new_head], %[new_head], %[new_head], lsl #16 \n"
+ " orrne %[new_head], %[old_head], %[new_head], lsl #16 \n"
+ " \n"
+ " bne.n 2f \n"
+ " \n"
+ " ldr %[old_head], [%[p_fifo], %[offset_tail]] \n"
+ " cmp %[old_head], %[old_head], ror #16 \n"
+ " it eq \n"
+ " moveq %[ret], %[true_val] \n"
+ " \n"
+ "2: \n"
+ " strex %[old_head], %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " cmp %[old_head], #0 \n"
+ " bne.n 1b \n"
+ : /* Output operands */
+ [ret] "=&r"(ret),
+ [old_head] "=&r"(old_head),
+ [new_head] "=&r"(new_head)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_head] "J"(offsetof(nrf_atfifo_t, head)),
+ [offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
+ [offset_tail_rd] "J"(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)),
+ [true_val] "I"(true),
+ [false_val] "I"(false)
+ : /* Clobbers */
+ "cc");
+
+ UNUSED_VARIABLE(old_head);
+ UNUSED_VARIABLE(new_head);
+ return ret;
+}
+
+#else
+#error Unsupported compiler
+#endif
+
+#endif /* NRF_ATFIFO_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c
new file mode 100644
index 0000000..b1d9ce2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "nrf_atflags.h"
+#include "sdk_common.h"
+
+
+
+/**@brief Macro for getting the index inside the flag array where a flag can be found.
+ *
+ * @param flag_index Index of the flag.
+ *
+ * @return Index of the @ref nrf_atflags_t the flag can be found in.
+ */
+#define FLAG_BASE(flag_index) ((flag_index) / NRF_ATFLAGS_FLAGS_PER_ELEMENT)
+
+/**@brief Macro for getting the mask representing the flag within the flag array member.
+ *
+ * @param flag_index ID of the flag.
+ *
+ * @return Mask representing the flag within a single @ref nrf_atflags_t.
+ */
+#define FLAG_MASK(flag_index) (1UL << ((flag_index) % NRF_ATFLAGS_FLAGS_PER_ELEMENT))
+
+
+void nrf_atflags_set(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ uint32_t new_value = nrf_atomic_u32_or(&p_flags[FLAG_BASE(flag_index)], FLAG_MASK(flag_index));
+ UNUSED_RETURN_VALUE(new_value);
+}
+
+
+bool nrf_atflags_fetch_set(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ return (nrf_atomic_u32_fetch_or(&p_flags[FLAG_BASE(flag_index)], FLAG_MASK(flag_index))
+ & FLAG_MASK(flag_index)) != 0;
+}
+
+
+void nrf_atflags_clear(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ uint32_t new_value = nrf_atomic_u32_and(&p_flags[FLAG_BASE(flag_index)], ~FLAG_MASK(flag_index));
+ UNUSED_RETURN_VALUE(new_value);
+}
+
+
+bool nrf_atflags_fetch_clear(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ return (nrf_atomic_u32_fetch_and(&p_flags[FLAG_BASE(flag_index)], ~FLAG_MASK(flag_index))
+ & FLAG_MASK(flag_index)) != 0;
+}
+
+
+bool nrf_atflags_get(nrf_atflags_t const * p_flags, uint32_t flag_index)
+{
+ return (p_flags[FLAG_BASE(flag_index)] & FLAG_MASK(flag_index)) != 0;
+}
+
+
+uint32_t nrf_atflags_init(nrf_atflags_t * p_flags, uint32_t flags_array_len, uint32_t flag_count)
+{
+ uint32_t required_flags_array_len = NRF_ATFLAGS_ARRAY_LEN(flag_count);
+
+ if (required_flags_array_len <= flags_array_len)
+ {
+ for (uint32_t i = 0; i < required_flags_array_len; i++)
+ {
+ p_flags[i] = 0;
+ }
+ return required_flags_array_len;
+ }
+ return 0;
+}
+
+uint32_t nrf_atflags_find_and_set_flag(nrf_atflags_t * p_flags, uint32_t flag_count)
+{
+ for (uint32_t i = 0; i < NRF_ATFLAGS_ARRAY_LEN(flag_count); i++)
+ {
+ // Using __RBIT to make the order of flags more traditional.
+ uint32_t first_zero = __CLZ(__RBIT(~p_flags[i]));
+ while (first_zero < 32)
+ {
+ uint32_t first_zero_global = first_zero + (i * 32);
+ if (first_zero_global >= flag_count)
+ {
+ break;
+ }
+ if (!nrf_atflags_fetch_set(p_flags, first_zero_global))
+ {
+ return first_zero_global;
+ }
+ first_zero = __CLZ(__RBIT(~p_flags[i]));
+ }
+ }
+
+ return flag_count;
+}
+
+uint32_t nrf_atflags_find_and_clear_flag(nrf_atflags_t * p_flags, uint32_t flag_count)
+{
+ for (uint32_t i = 0; i < NRF_ATFLAGS_ARRAY_LEN(flag_count); i++)
+ {
+ // Using __RBIT to make the order of flags more traditional.
+ uint32_t first_one = __CLZ(__RBIT(p_flags[i]));
+ while (first_one < 32)
+ {
+ uint32_t first_one_global = first_one + (i * 32);
+ if (first_one_global >= flag_count)
+ {
+ break;
+ }
+ if (nrf_atflags_fetch_clear(p_flags, first_one_global))
+ {
+ return first_one_global;
+ }
+ first_one = __CLZ(__RBIT(p_flags[i]));
+ }
+ }
+
+ return flag_count;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h
new file mode 100644
index 0000000..79bde42
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_atflags Atomic flags (bitmaps)
+ * @ingroup app_common
+ * @{
+ *
+ * @brief @tagAPI52 This module implements atomic flags as bitmaps.
+ *
+ * Operations on the individual flags are atomic, meaning that you are always sure that the flag is
+ * set to the desired value, and you always know what value was there before. You also know that no
+ * other flags were affected by the operation.
+ *
+ * Operations on the entire flag collection are NOT atomic. This essentially means that you can't
+ * know the order in which operations on different flags happened, and you can't know the state of
+ * the entire flag collection at any instant. These limitations can be overcome by protecting
+ * operations with a mutex.
+ */
+
+#ifndef NRF_ATFLAGS_H__
+#define NRF_ATFLAGS_H__
+
+
+/**
+ * @brief Array of atomic flags.
+ * */
+typedef volatile uint32_t nrf_atflags_t;
+
+
+/**
+ * @brief Number of flags per @ref nrf_atflags_t.
+ * */
+#define NRF_ATFLAGS_FLAGS_PER_ELEMENT (sizeof(nrf_atflags_t) * 8)
+
+/**@brief Macro for the length of an array of @ref nrf_atflags_t needed to keep \p flag_count flags.
+ *
+ * @param flag_count Number of flags to keep in a flag array.
+ *
+ * @return Length of the array needed to house flag_count flags.
+ */
+#define NRF_ATFLAGS_ARRAY_LEN(flag_count) ((flag_count - 1) / NRF_ATFLAGS_FLAGS_PER_ELEMENT) + 1
+
+/**@brief Macro for declaring a flag array with the right size and initial value.
+ *
+ * @note When using this macro, no call to @ref nrf_atflags_init is necessary for this array.
+ *
+ * @param _name Name to be given to the array.
+ * @param flag_count Number of flags to be kept in the flag array.
+ *
+ * @return Flag array definition.
+ */
+#define NRF_ATFLAGS_DEF(_name, flag_count) \
+ nrf_atflags_t _name[NRF_ATFLAGS_ARRAY_LEN((flag_count))] = {0}
+
+/**@brief Macro for declaring a flag array with the right size as a member of a struct.
+ *
+ * @note When using this macro, make sure to set the array to 0 or use @ref nrf_atflags_init
+ *
+ * @param _name Name to be given to the array.
+ * @param flag_count Number of flags to be kept in the flag array.
+ *
+ * @return Flag array definition.
+ */
+#define NRF_ATFLAGS_DEF_MEMBER(_name, flag_count) \
+ nrf_atflags_t _name[NRF_ATFLAGS_ARRAY_LEN((flag_count))]
+
+
+/**@brief Function for safely initializing a flag array to 0.
+ *
+ * @param p_flags Flag array to initialize.
+ * @param flags_array_len Length of \p p_flags.
+ * @param flag_count Number of flags to be kept in the flag array.
+ *
+ * @retval 0 if the given length is not sufficient to house \p flag_count flags in the array.
+ * @return If successful: The actual length required.
+ */
+uint32_t nrf_atflags_init(nrf_atflags_t * p_flags, uint32_t flags_array_len, uint32_t flag_count);
+
+/**@brief Function for atomically setting a flag to 1.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ */
+void nrf_atflags_set(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for atomically setting a flag to 1, returning the previous value of the flag.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ *
+ * @return Old flag value.
+ */
+bool nrf_atflags_fetch_set(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for atomically setting a flag to 0.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ */
+void nrf_atflags_clear(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for atomically setting a flag to 0, returning the previous value of the flag.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ *
+ * @return Old flag value.
+ */
+bool nrf_atflags_fetch_clear(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for getting the value of a flag in a flag array.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ *
+ * @return Flag value.
+ */
+bool nrf_atflags_get(nrf_atflags_t const * p_flags, uint32_t flag_index);
+
+/**@brief Function for finding a flag with value 0, and atomically setting it to one.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_count Number of flags in the array.
+ *
+ * @return Index of the cleared flag that has been set.
+ */
+uint32_t nrf_atflags_find_and_set_flag(nrf_atflags_t * p_flags, uint32_t flag_count);
+
+/**@brief Function for finding a flag with value 1, and atomically clearing it to 0.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_count The number of flags in the array.
+ *
+ * @return The index of the set flag that has been cleared.
+ */
+uint32_t nrf_atflags_find_and_clear_flag(nrf_atflags_t * p_flags, uint32_t flag_count);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATFLAGS_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c
new file mode 100644
index 0000000..d228f32
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c
@@ -0,0 +1,399 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+ #if NRF_MODULE_ENABLED(NRF_BALLOC)
+
+#include "nrf_section.h"
+#include "nrf_balloc.h"
+#include "app_util_platform.h"
+
+
+#if NRF_BALLOC_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_BALLOC_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INITIAL_LEVEL NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_BALLOC_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_BALLOC_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_BALLOC_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+
+#define HEAD_GUARD_FILL 0xBAADF00D /**< Magic number used to mark head guard.*/
+#define TAIL_GUARD_FILL 0xBAADCAFE /**< Magic number used to mark tail guard.*/
+#define FREE_MEM_FILL 0xBAADBAAD /**< Magic number used to mark free memory.*/
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define POOL_ID(_p_pool) _p_pool->p_name
+#define POOL_MARKER "%s"
+#else
+#define POOL_ID(_p_pool) _p_pool
+#define POOL_MARKER "0x%08X"
+#endif
+
+NRF_SECTION_DEF(nrf_balloc, nrf_balloc_t);
+
+#if NRF_BALLOC_CLI_CMDS
+#include "nrf_cli.h"
+
+static void nrf_balloc_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc > 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad argument count");
+ return;
+ }
+
+ uint32_t num_of_instances = NRF_SECTION_ITEM_COUNT(nrf_balloc, nrf_balloc_t);
+ uint32_t i;
+
+ for (i = 0; i < num_of_instances; i++)
+ {
+ const nrf_balloc_t * p_instance = NRF_SECTION_ITEM_GET(nrf_balloc, nrf_balloc_t, i);
+
+ uint32_t element_size = NRF_BALLOC_ELEMENT_SIZE(p_instance);
+ uint32_t dbg_addon = p_instance->block_size - element_size;
+ uint32_t pool_size = p_instance->p_stack_limit - p_instance->p_stack_base;
+ uint32_t max_util = nrf_balloc_max_utilization_get(p_instance);
+ uint32_t util = nrf_balloc_utilization_get(p_instance);
+ const char * p_name = p_instance->p_name;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL,
+ "%s\r\n\t- Element size:\t%d + %d bytes of debug information\r\n"
+ "\t- Usage:\t%u%% (%u out of %u elements)\r\n"
+ "\t- Maximum:\t%u%% (%u out of %u elements)\r\n\r\n",
+ p_name, element_size, dbg_addon,
+ 100ul * util/pool_size, util,pool_size,
+ 100ul * max_util/pool_size, max_util,pool_size);
+
+ }
+}
+// Register "balloc" command and its subcommands in CLI.
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_balloc_commands)
+{
+ NRF_CLI_CMD(status, NULL, "Print status of balloc instances.", nrf_balloc_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(balloc, &nrf_balloc_commands, "Commands for BALLOC management", nrf_balloc_status);
+#endif //NRF_BALLOC_CLI_CMDS
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+/**@brief Validate block memory, prepare block guards, and calculate pointer to the element.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_head Pointer to the beginning of the block.
+ *
+ * @return Pointer to the element.
+ */
+__STATIC_INLINE void * nrf_balloc_block_unwrap(nrf_balloc_t const * p_pool, void * p_head)
+{
+ ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
+ ASSERT((p_head != NULL) && (((uint32_t)(p_head) % sizeof(uint32_t)) == 0));
+
+ uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
+ uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
+
+ uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
+ uint32_t * p_element = (uint32_t *)p_head + head_words;
+
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
+ {
+ if (*ptr != FREE_MEM_FILL)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Detected free memory corruption at 0x%08X (0x%08X != 0x%08X)",
+ ptr, *ptr, FREE_MEM_FILL);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ }
+
+ for (uint32_t * ptr = p_head; ptr < p_element; ptr++)
+ {
+ *ptr = HEAD_GUARD_FILL;
+ }
+
+ for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
+ {
+ *ptr = TAIL_GUARD_FILL;
+ }
+
+ return p_element;
+}
+
+/**@brief Calculate pointer to the block, validate block guards, and mark block memory as free.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_element Pointer to the element.
+ *
+ * @return Pointer to the beginning of the block.
+ */
+__STATIC_INLINE void * nrf_balloc_element_wrap(nrf_balloc_t const * p_pool, void * p_element)
+{
+ ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
+ ASSERT((p_element != NULL) && (((uint32_t)(p_element) % sizeof(uint32_t)) == 0));
+
+ uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
+ uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
+
+ uint32_t * p_head = (uint32_t *)p_element - head_words;
+ uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
+
+ for (uint32_t * ptr = p_head; ptr < (uint32_t *)p_element; ptr++)
+ {
+ if (*ptr != HEAD_GUARD_FILL)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Detected Head Guard corruption at 0x%08X (0x%08X != 0x%08X)",
+ ptr, *ptr, HEAD_GUARD_FILL);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
+ {
+ if (*ptr != TAIL_GUARD_FILL)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Detected Tail Guard corruption at 0x%08X (0x%08X != 0x%08X)",
+ ptr, *ptr, TAIL_GUARD_FILL);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
+ {
+ *ptr = FREE_MEM_FILL;
+ }
+ }
+
+ return p_head;
+}
+
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Convert block index to a pointer.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] idx Index of the block.
+ *
+ * @return Pointer to the beginning of the block.
+ */
+static void * nrf_balloc_idx2block(nrf_balloc_t const * p_pool, uint8_t idx)
+{
+ ASSERT(p_pool != NULL);
+ return (uint8_t *)(p_pool->p_memory_begin) + ((size_t)(idx) * p_pool->block_size);
+}
+
+/**@brief Convert block pointer to index.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_block Pointer to the beginning of the block.
+ *
+ * @return Index of the block.
+ */
+static uint8_t nrf_balloc_block2idx(nrf_balloc_t const * p_pool, void const * p_block)
+{
+ ASSERT(p_pool != NULL);
+ return ((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) / p_pool->block_size;
+}
+
+ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool)
+{
+ uint8_t pool_size;
+
+ VERIFY_PARAM_NOT_NULL(p_pool);
+
+ ASSERT(p_pool->p_cb);
+ ASSERT(p_pool->p_stack_base);
+ ASSERT(p_pool->p_stack_limit);
+ ASSERT(p_pool->p_memory_begin);
+ ASSERT(p_pool->block_size);
+
+ pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_pool->p_memory_begin; ptr < (uint32_t *)(p_memory_end); ptr++)
+ {
+ *ptr = FREE_MEM_FILL;
+ }
+ }
+#endif
+
+ NRF_LOG_INST_INFO(p_pool->p_log, "Initialized (size: %u x %u = %u bytes)",
+ pool_size,
+ p_pool->block_size,
+ pool_size * p_pool->block_size);
+
+ p_pool->p_cb->p_stack_pointer = p_pool->p_stack_base;
+ while (pool_size--)
+ {
+ *(p_pool->p_cb->p_stack_pointer)++ = pool_size;
+ }
+
+ p_pool->p_cb->max_utilization = 0;
+
+ return NRF_SUCCESS;
+}
+
+void * nrf_balloc_alloc(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+
+ void * p_block = NULL;
+
+ CRITICAL_REGION_ENTER();
+
+ if (p_pool->p_cb->p_stack_pointer > p_pool->p_stack_base)
+ {
+ // Allocate block.
+ p_block = nrf_balloc_idx2block(p_pool, *--(p_pool->p_cb->p_stack_pointer));
+
+ // Update utilization statistics.
+ uint8_t utilization = p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer;
+ if (p_pool->p_cb->max_utilization < utilization)
+ {
+ p_pool->p_cb->max_utilization = utilization;
+ }
+ }
+
+ CRITICAL_REGION_EXIT();
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ if (p_block != NULL)
+ {
+ p_block = nrf_balloc_block_unwrap(p_pool, p_block);
+ }
+#endif
+
+ NRF_LOG_INST_DEBUG(p_pool->p_log, "Allocating element: 0x%08X", p_block);
+
+ return p_block;
+}
+
+void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element)
+{
+ ASSERT(p_pool != NULL);
+ ASSERT(p_element != NULL)
+
+ NRF_LOG_INST_DEBUG(p_pool->p_log, "Freeing element: 0x%08X", p_element);
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ void * p_block = nrf_balloc_element_wrap(p_pool, p_element);
+
+ // These checks could be done outside critical region as they use only pool configuration data.
+ if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
+ {
+ uint8_t pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
+ void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
+
+ // Check if the element belongs to this pool.
+ if ((p_block < p_pool->p_memory_begin) || (p_block >= p_memory_end))
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Attempted to free element (0x%08X) that does not belong to the pool.",
+ p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ // Check if the pointer is valid.
+ if ((((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) % p_pool->block_size) != 0)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Attempted to free corrupted element address (0x%08X).", p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+#else
+ void * p_block = p_element;
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+ CRITICAL_REGION_ENTER();
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ // These checks have to be done in critical region as they use p_pool->p_stack_pointer.
+ if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
+ {
+ // Check for allocated/free ballance.
+ if (p_pool->p_cb->p_stack_pointer >= p_pool->p_stack_limit)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Attempted to free an element (0x%08X) while the pool is full.",
+ p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ if (NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(p_pool->debug_flags))
+ {
+ // Check for double free.
+ for (uint8_t * p_idx = p_pool->p_stack_base; p_idx < p_pool->p_cb->p_stack_pointer; p_idx++)
+ {
+ if (nrf_balloc_idx2block(p_pool, *p_idx) == p_block)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log, "Attempted to double-free an element (0x%08X).",
+ p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ }
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+ // Free the element.
+ *(p_pool->p_cb->p_stack_pointer)++ = nrf_balloc_block2idx(p_pool, p_block);
+
+ CRITICAL_REGION_EXIT();
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_BALLOC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h
new file mode 100644
index 0000000..0f781a6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h
@@ -0,0 +1,351 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * @defgroup nrf_balloc Block memory allocator
+ * @{
+ * @ingroup app_common
+ * @brief This module handles block memory allocator features.
+ */
+
+
+#ifndef NRF_BALLOC_H__
+#define NRF_BALLOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "app_util_platform.h"
+#include "app_util.h"
+#include "nrf_log_instance.h"
+#include "nrf_section.h"
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define NRF_BALLOC_LOG_NAME balloc
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED || NRF_BALLOC_CLI_CMDS
+#define NRF_BALLOC_HAS_NAME 1
+#else
+#define NRF_BALLOC_HAS_NAME 0
+#endif
+
+/**@defgroup NRF_BALLOC_DEBUG Macros for preparing debug flags for block allocator module.
+ * @{ */
+#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(words) (((words) & 0xFF) << 0)
+#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(flags) (((flags) >> 0) & 0xFF)
+#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(words) (((words) & 0xFF) << 8)
+#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(flags) (((flags) >> 8) & 0xFF)
+
+#define NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(enable) (!!(enable) << 16)
+#define NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(flags) (flags & (1 << 16))
+#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(enable) (!!(enable) << 17)
+#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(flags) (flags & (1 << 17))
+#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(enable) (!!(enable) << 18)
+#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(flags) (flags & (1 << 18))
+/**@} */
+
+/**@brief Default debug flags for @ref nrf_balloc. This is used by the @ref NRF_BALLOC_DEF macro.
+ * Flags can be changed in @ref sdk_config.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS \
+ ( \
+ NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS) | \
+ NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS) | \
+ NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED) | \
+ NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED) | \
+ NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED) \
+ )
+#else
+ #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS 0
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Block memory allocator control block.*/
+typedef struct
+{
+ uint8_t * p_stack_pointer; //!< Current allocation stack pointer.
+ uint8_t max_utilization; //!< Maximum utilization of the memory pool.
+} nrf_balloc_cb_t;
+
+/**@brief Block memory allocator pool instance. The pool is made of elements of the same size. */
+typedef struct
+{
+ nrf_balloc_cb_t * p_cb; //!< Pointer to the instance control block.
+ uint8_t * p_stack_base; //!< Base of the allocation stack.
+ /**<
+ * Stack is used to store handlers to not allocated elements.
+ */
+ uint8_t * p_stack_limit; //!< Maximum possible value of the allocation stack pointer.
+ void * p_memory_begin; //!< Pointer to the start of the memory pool.
+ /**<
+ * Memory is used as a heap for blocks.
+ */
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
+#if NRF_BALLOC_HAS_NAME
+ const char * p_name; //!< Pointer to string with pool name.
+#endif
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ uint32_t debug_flags; //!< Debugging settings.
+ /**<
+ * Debug flag should be created by @ref NRF_BALLOC_DEBUG.
+ */
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ uint16_t block_size; //!< Size of the allocated block (including debug overhead).
+ /**<
+ * Single block contains user element with header and tail
+ * words.
+ */
+} nrf_balloc_t;
+
+/**@brief Get total memory consumed by single block (element size with overhead caused by debug
+ * flags).
+ *
+ * @param[in] _element_size Size of an element.
+ * @param[in] _debug_flags Debug flags.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
+ ( \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(_debug_flags)) + \
+ ALIGN_NUM(sizeof(uint32_t), (_element_size)) + \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(_debug_flags)) \
+ )
+#else
+ #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
+ ALIGN_NUM(sizeof(uint32_t), (_element_size))
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+
+/**@brief Get element size ( excluding debugging overhead is present)
+ * flags).
+ *
+ * @param[in] _p_balloc Pointer to balloc instance.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
+ (ALIGN_NUM(sizeof(uint32_t), (_p_balloc)->block_size) - \
+ ((sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET((_p_balloc)->debug_flags)) + \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET((_p_balloc)->debug_flags))))
+#else
+#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
+ (_p_balloc)->block_size
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) .debug_flags = (_debug_flags),
+#else
+#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags)
+#endif
+
+#if NRF_BALLOC_HAS_NAME
+#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name) .p_name = STRINGIFY(_name),
+#else
+#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name)
+#endif
+
+
+/**@brief Create a block allocator instance with custom debug flags.
+ *
+ * @note This macro reserves memory for the given block allocator instance.
+ *
+ * @param[in] _name Name of the allocator.
+ * @param[in] _element_size Size of one element.
+ * @param[in] _pool_size Size of the pool.
+ * @param[in] _debug_flags Debug flags (@ref NRF_BALLOC_DEBUG).
+ */
+#define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \
+ STATIC_ASSERT((_pool_size) <= UINT8_MAX); \
+ static uint8_t CONCAT_2(_name, _nrf_balloc_pool_stack)[(_pool_size)]; \
+ static uint32_t CONCAT_2(_name,_nrf_balloc_pool_mem) \
+ [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \
+ static nrf_balloc_cb_t CONCAT_2(_name,_nrf_balloc_cb); \
+ NRF_LOG_INSTANCE_REGISTER(NRF_BALLOC_LOG_NAME, _name, \
+ NRF_BALLOC_CONFIG_INFO_COLOR, \
+ NRF_BALLOC_CONFIG_DEBUG_COLOR, \
+ NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL, \
+ NRF_BALLOC_CONFIG_LOG_ENABLED ? \
+ NRF_BALLOC_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ NRF_SECTION_ITEM_REGISTER(nrf_balloc, const nrf_balloc_t _name) = \
+ { \
+ .p_cb = &CONCAT_2(_name,_nrf_balloc_cb), \
+ .p_stack_base = CONCAT_2(_name,_nrf_balloc_pool_stack), \
+ .p_stack_limit = CONCAT_2(_name,_nrf_balloc_pool_stack) + (_pool_size), \
+ .p_memory_begin = CONCAT_2(_name,_nrf_balloc_pool_mem), \
+ .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \
+ \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_BALLOC_LOG_NAME, _name) \
+ __NRF_BALLOC_ASSIGN_POOL_NAME(_name) \
+ __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) \
+ }
+
+/**@brief Create a block allocator instance.
+ *
+ * @note This macro reserves memory for the given block allocator instance.
+ *
+ * @param[in] _name Name of the allocator.
+ * @param[in] _element_size Size of one element.
+ * @param[in] _pool_size Size of the pool.
+ */
+#define NRF_BALLOC_DEF(_name, _element_size, _pool_size) \
+ NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, NRF_BALLOC_DEFAULT_DEBUG_FLAGS)
+
+/**@brief Create a block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ */
+#define NRF_BALLOC_INTERFACE_DEC(_type, _name) \
+ _type * CONCAT_2(_name,_alloc)(void); \
+ void CONCAT_2(_name,_free)(_type * p_element)
+
+/**@brief Define a custom block allocator interface.
+ *
+ * @param[in] _attr Function attribute that will be added to allocator function definition.
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_pool) \
+ _attr _type * CONCAT_2(_name,_alloc)(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_pool) != NULL); \
+ ASSERT((_p_pool)->block_size >= \
+ NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return (_type *)(nrf_balloc_alloc(_p_pool)); \
+ } \
+ \
+ _attr void CONCAT_2(_name,_free)(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_pool) != NULL); \
+ ASSERT((_p_pool)->block_size >= \
+ NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ nrf_balloc_free((_p_pool), p_element); \
+ }
+
+/**@brief Define block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_DEF(_type, _name, _p_pool) \
+ NRF_BALLOC_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_pool)
+
+/**@brief Define a local block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_LOCAL_DEF(_type, _name, _p_pool) \
+ NRF_BALLOC_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_pool)
+
+/**@brief Function for initializing a block memory allocator pool.
+ *
+ * @param[out] p_pool Pointer to the pool that is to be initialized.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool);
+
+/**@brief Function for allocating an element from the pool.
+ *
+ * @note This module guarantees that the returned memory is aligned to 4.
+ *
+ * @param[in] p_pool Pointer to the memory pool from which the element will be allocated.
+ *
+ * @return Allocated element or NULL if the specified pool is empty.
+ */
+void * nrf_balloc_alloc(nrf_balloc_t const * p_pool);
+
+/**@brief Function for freeing an element back to the pool.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_element Element to be freed.
+ */
+void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element);
+
+/**@brief Function for getting maximum memory pool utilization.
+ *
+ * @param[in] p_pool Pointer to the memory pool instance.
+ *
+ * @return Maximum number of elements allocated from the pool.
+ */
+__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+ return p_pool->p_cb->max_utilization;
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+/**@brief Function for getting current memory pool utilization.
+ *
+ * @param[in] p_pool Pointer to the memory pool instance.
+ *
+ * @return Maximum number of elements allocated from the pool.
+ */
+__STATIC_INLINE uint8_t nrf_balloc_utilization_get(nrf_balloc_t const * p_pool);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_balloc_utilization_get(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+ return (p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BALLOC_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c
new file mode 100644
index 0000000..ab9f5c7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c
@@ -0,0 +1,210 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_block_dev_empty.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ * @brief This module implements block device API. It would behave like:
+ * - /dev/empty for write operations
+ * - /dev/zero for read operations
+ */
+
+static ret_code_t block_dev_empty_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ /* Calculate block device geometry.... */
+ p_work->geometry.blk_size = p_empty_dev->empty_config.block_size;
+ p_work->geometry.blk_count = p_empty_dev->empty_config.block_count;
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ memset(p_work, 0, sizeof(nrf_block_dev_empty_work_t));
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ memset(p_blk->p_buff, 0, p_empty_dev->p_work->geometry.blk_size * p_blk->blk_count);
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ p_blk,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ p_blk,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req, void * p_data)
+{
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+ return NRF_SUCCESS;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_empty_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static nrf_block_dev_geometry_t const * block_dev_empty_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t const * p_work = p_empty_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_empty_ops = {
+ .init = block_dev_empty_init,
+ .uninit = block_dev_empty_uninit,
+ .read_req = block_dev_empty_read_req,
+ .write_req = block_dev_empty_write_req,
+ .ioctl = block_dev_empty_ioctl,
+ .geometry = block_dev_empty_geometry,
+};
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h
new file mode 100644
index 0000000..2f2dc76
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_EMPTY_H__
+#define NRF_BLOCK_DEV_EMPTY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+
+
+/**@file
+ *
+ * @defgroup nrf_block_dev_empty Empty implementation
+ * @ingroup nrf_block_dev
+ *
+ * This module implements block device API. It works like:
+ * - /dev/empty for write operations
+ * - /dev/zero for read operations
+ * @{
+ *
+ */
+
+/**
+ * @brief EMPTY block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_empty_ops;
+
+/**
+ * @brief Work structure of EMPTY block device.
+ */
+typedef struct {
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ void const * p_context; //!< Context handle passed to event handler
+} nrf_block_dev_empty_work_t;
+
+
+/**
+ * @brief EMPTY block device config initializer (@ref nrf_block_dev_empty_config_t)
+ *
+ * @param blk_size Block size
+ * @param blk_count Block count
+ * */
+#define NRF_BLOCK_DEV_EMPTY_CONFIG(blk_size, blk_count) { \
+ .block_size = (blk_size), \
+ .block_count = (blk_count) \
+}
+
+/**
+ * @brief EMPTY block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ uint32_t block_count; //!< Desired block count
+} nrf_block_dev_empty_config_t;
+
+/**
+ * @brief EMPTY block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_empty_config_t empty_config; //!< EMPTY block device config
+ nrf_block_dev_empty_work_t * p_work; //!< EMPTY block device work structure
+} nrf_block_dev_empty_t;
+
+/**
+ * @brief Defines a EMPTY block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_empty_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_EMPTY_DEFINE(name, config, info) \
+ static nrf_block_dev_empty_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_empty_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_empty_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .empty_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from EMPTY block device.
+ *
+ * @param[in] p_blk_empty EMPTY block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_empty_ops_get(nrf_block_dev_empty_t const * p_blk_empty)
+{
+ return &p_blk_empty->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_EMPTY_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h
new file mode 100644
index 0000000..5d3c5c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_H__
+#define NRF_BLOCK_DEV_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_common.h"
+#include "nrf_assert.h"
+
+#include <stddef.h>
+
+/**@file
+ *
+ * @defgroup nrf_block_dev Block device
+ * @{
+ * @ingroup app_common
+ *
+ * @brief This module implements unified block device API. It could used as a middle layer between
+ * filesystems and memories.
+ */
+
+/**
+ * @brief Block device request descriptor item.
+ */
+typedef struct {
+ uint32_t blk_id; //!< Block ID
+ uint32_t blk_count; //!< Block count
+ void * p_buff; //!< Data buffer
+} nrf_block_req_t;
+
+
+/**
+ * @brief Helper macro to create block device read/write request item
+ *
+ * @param name Instance name
+ * @param block_start Block number start
+ * @param block_count Number of blocks
+ * @param buff Buffer to read/write
+ */
+#define NRF_BLOCK_DEV_REQUEST(name, block_start, block_count, buff) \
+ nrf_block_req_t name = { \
+ .blk_id = block_start, \
+ .blk_count = block_count, \
+ .p_buff = buff, \
+ }
+/**
+ * @brief Block device events.
+ *
+ * Events are propagated when event handler is defined (@ref nrf_blk_dev_init)
+ *
+ */
+typedef enum {
+ NRF_BLOCK_DEV_EVT_INIT, /**< Passed to event handler when init is done*/
+ NRF_BLOCK_DEV_EVT_UNINIT, /**< Passed to event handler when uninit is done*/
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE, /**< Passed to event handler block read operation is done*/
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, /**< Passed to event handler block write operation is done*/
+} nrf_block_dev_event_type_t;
+
+typedef enum {
+ NRF_BLOCK_DEV_RESULT_SUCCESS = 0, /**< Operation completed succsefully*/
+ NRF_BLOCK_DEV_RESULT_IO_ERROR, /**< I/O error*/
+ NRF_BLOCK_DEV_RESULT_TIMEOUT, /**< Device timeout*/
+} nrf_block_dev_result_t;
+
+/**
+ * @brief Block device event
+ * */
+typedef struct {
+ nrf_block_dev_event_type_t ev_type; //!< Event type
+ nrf_block_dev_result_t result; //!< Operation status
+ nrf_block_req_t const * p_blk_req; //!< Block request
+ void const * p_context; //!< Event context
+} nrf_block_dev_event_t;
+
+struct nrf_block_dev_s;
+
+/**
+ * @brief Block device event handler.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] p_event Block device event
+ */
+typedef void (* nrf_block_dev_ev_handler)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event);
+
+/**
+ * @brief Block device geometry
+ */
+typedef struct {
+ uint32_t blk_count; //!< Block count
+ uint32_t blk_size; //!< Block size
+} nrf_block_dev_geometry_t;
+
+/**
+ * @brief Block device information strings
+ */
+typedef struct {
+ const char * p_vendor; //!< Vendor string
+ const char * p_product; //!< Product string
+ const char * p_revision; //!< Revision string
+} nrf_block_dev_info_strings_t;
+
+/**
+ * @brief Block device information config
+ *
+ * @param vendor Vendor string
+ * @param product Product string
+ * @param revision Revision string
+ * */
+#define NFR_BLOCK_DEV_INFO_CONFIG(vendor, product, revision) ( { \
+ .p_vendor = vendor, \
+ .p_product = product, \
+ .p_revision = revision, \
+})
+
+/**
+ * @brief Empty info string initializer
+ * */
+#define NFR_BLOCK_DEV_INFO_CONFIG_EMPTY \
+ NFR_BLOCK_DEV_INFO_CONFIG(NULL, NULL, NULL)
+
+/**
+ * @brief Block device IOCTL requests
+ */
+typedef enum {
+ NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH = 0, /**< Cache flush IOCTL request*/
+ NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS, /**< Get info strings IOCTL request*/
+} nrf_block_dev_ioctl_req_t;
+
+
+/**
+ * @brief Helper macro to get block device address from specific instance
+ *
+ * @param instance Block device instance
+ * @param member Block device member name
+ * */
+#define NRF_BLOCKDEV_BASE_ADDR(instance, member) &(instance).member
+
+/**
+ * @brief Block device API
+ * */
+typedef struct nrf_block_dev_s {
+ struct nrf_block_dev_ops_s {
+ /**
+ * @brief @ref nrf_blk_dev_init
+ */
+ ret_code_t (*init)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context);
+
+ /**
+ * @brief @ref nrf_blk_dev_uninit
+ */
+ ret_code_t (*uninit)(struct nrf_block_dev_s const * p_blk_dev);
+
+ /**
+ * @brief @ref nrf_blk_dev_read_req
+ */
+ ret_code_t (*read_req)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_req_t const * p_blk);
+
+ /**
+ * @brief @ref nrf_blk_dev_write_req
+ */
+ ret_code_t (*write_req)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_req_t const * p_blk);
+
+ /**
+ * @brief @ref nrf_blk_dev_ioctl
+ */
+ ret_code_t (*ioctl)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data);
+
+ /**
+ * @brief @ref nrf_blk_dev_geometry
+ */
+ nrf_block_dev_geometry_t const * (*geometry)(struct nrf_block_dev_s const * p_blk_dev);
+ } const * p_ops;
+} nrf_block_dev_t;
+
+/**
+ * @brief Internals of @ref nrf_block_dev_t
+ * */
+typedef struct nrf_block_dev_ops_s nrf_block_dev_ops_t;
+
+/**
+ * @brief Initializes a block device.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] ev_handler Event handler (pass NULL to work in synchronous mode)
+ * @param[in] p_context Context passed to event handler
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev->p_ops->init);
+ return p_blk_dev->p_ops->init(p_blk_dev, ev_handler, p_context);
+}
+
+/**
+ * @brief Un-initializes a block device.
+ *
+ * @param[in] p_blk_dev Block device handle
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev->p_ops->uninit);
+ return p_blk_dev->p_ops->uninit(p_blk_dev);
+}
+
+/**
+ * @brief Block read request.
+ *
+ * In synchronous mode this function will execute the read operation
+ * and wait for its completion. In asynchronous mode the function will only request
+ * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE
+ * event will signal that operation has been completed and the specified buffer contains
+ * valid data.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] p_blk Block device request
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev->p_ops->read_req);
+ ASSERT(p_blk_dev->p_ops->geometry);
+
+ if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return p_blk_dev->p_ops->read_req(p_blk_dev, p_blk);
+}
+
+/**
+ * @brief Block write request.
+ *
+ * In synchronous mode this function will execute the write operation
+ * and wait for its completion. In asynchronous mode the function will only request
+ * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE
+ * event will signal that operation has been completed and the specified buffer
+ * can be freed.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] p_blk Block device request
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev->p_ops->write_req);
+ ASSERT(p_blk_dev->p_ops->geometry);
+
+ if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return p_blk_dev->p_ops->write_req(p_blk_dev, p_blk);
+}
+
+/**
+ * @brief IO control function.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] req Block device ioctl request
+ * @param[in] p_data Block device ioctl data
+ *
+ * @return Standard error code
+ * */
+static inline ret_code_t nrf_blk_dev_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ ASSERT(p_blk_dev->p_ops->ioctl);
+ return p_blk_dev->p_ops->ioctl(p_blk_dev, req, p_data);
+}
+
+/**
+ * @brief Return a geometry of a block device.
+ *
+ * @param[in] p_blk_dev Block device handle
+ *
+ * @return Block size and count @ref nrf_block_dev_geometry_t
+ */
+static inline nrf_block_dev_geometry_t const *
+nrf_blk_dev_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev->p_ops->geometry);
+ return p_blk_dev->p_ops->geometry(p_blk_dev);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_H__ */
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c
new file mode 100644
index 0000000..8ccac6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c
@@ -0,0 +1,757 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_serial_flash_params.h"
+#include "nrf_block_dev_qspi.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev_qspi
+ * @{
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+#define QSPI_STD_CMD_WRSR 0x01 /**< Write status register command*/
+#define QSPI_STD_CMD_RSTEN 0x66 /**< Reset enable command*/
+#define QSPI_STD_CMD_RST 0x99 /**< Reset command*/
+#define QSPI_STD_CMD_READ_ID 0x9F /**< Read ID command*/
+
+#define BD_PAGE_PROGRAM_SIZE 256 /**< Page program size (minimum block size)*/
+
+#define BD_ERASE_UNIT_INVALID_ID 0xFFFFFFFF /**< Invalid erase unit number*/
+#define BD_ERASE_UNIT_ERASE_VAL 0xFFFFFFFF /**< Erased memory value*/
+
+/**
+ * @brief Block to erase unit translation
+ *
+ * @param blk_id Block index
+ * @param blk_size Block size
+ * */
+#define BD_BLOCK_TO_ERASEUNIT(blk_id, blk_size) \
+ ((blk_id) * (blk_size)) / (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE)
+
+/**
+ * @brief Blocks per erase unit
+ *
+ * @param blk_size Block size
+ * */
+#define BD_BLOCKS_PER_ERASEUNIT(blk_size) \
+ (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE / (blk_size))
+
+
+static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev,
+ nrf_block_req_t * p_blk_left);
+
+
+static void block_dev_qspi_read_from_eunit(nrf_block_dev_qspi_t const * p_qspi_dev)
+{
+ nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work;
+
+ /*In write-back mode data that we read might not be the same as in erase unit buffer*/
+ uint32_t eunit_start = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id,
+ p_work->geometry.blk_size);
+
+ uint32_t eunit_end = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id + p_work->req.blk_count,
+ p_work->geometry.blk_size);
+
+ if ((eunit_start > p_work->erase_unit_idx) || (eunit_end < p_work->erase_unit_idx))
+ {
+ /*Do nothing. Read request doesn't hit current cached erase unit*/
+ return;
+ }
+
+ /*Case 1: Copy data from start erase unit*/
+ if (eunit_start == p_work->erase_unit_idx)
+ {
+ size_t blk = p_work->req.blk_id %
+ BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size);
+ size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk;
+ size_t off = p_work->geometry.blk_size * blk;
+
+ if (cnt > p_work->req.blk_count)
+ {
+ cnt = p_work->req.blk_count;
+ }
+
+ memcpy(p_work->req.p_buff,
+ p_work->p_erase_unit_buff + off,
+ cnt * p_work->geometry.blk_size);
+
+ return;
+ }
+
+ /*Case 2: Copy data from end erase unit*/
+ if (eunit_end == p_work->erase_unit_idx)
+ {
+ size_t cnt = (p_work->req.blk_id + p_work->req.blk_count) %
+ BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size);
+ size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) -
+ p_work->req.blk_id) * p_work->geometry.blk_size;
+
+ if (cnt > p_work->req.blk_count)
+ {
+ cnt = p_work->req.blk_count;
+ }
+
+ memcpy((uint8_t *)p_work->req.p_buff + off,
+ p_work->p_erase_unit_buff,
+ cnt * p_work->geometry.blk_size);
+
+ return;
+ }
+
+ /*Case 3: Copy data from eunit_start < p_work->erase_unit_idx < eunit_end*/
+ size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) -
+ p_work->req.blk_id) * p_work->geometry.blk_size;
+
+ memcpy((uint8_t *)p_work->req.p_buff + off,
+ p_work->p_erase_unit_buff,
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+}
+
+/**
+ * @brief Active QSPI block device handle. Only one instance.
+ * */
+static nrf_block_dev_qspi_t const * m_active_qspi_dev;
+
+static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context)
+{
+ if (m_active_qspi_dev != p_context)
+ {
+ return;
+ }
+
+ nrf_block_dev_qspi_t const * p_qspi_dev = p_context;
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+ nrf_block_req_t * p_blk_left = &p_work->left_req;
+
+ switch (p_work->state)
+ {
+ case NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC:
+ {
+ if (p_work->writeback_mode)
+ {
+ block_dev_qspi_read_from_eunit(p_qspi_dev);
+ }
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ if (p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ &p_work->req,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(&p_qspi_dev->block_dev, &ev);
+ }
+
+ break;
+ }
+ case NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD:
+ {
+ ret_code_t ret;
+ uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id,
+ p_work->geometry.blk_size);
+ UNUSED_VARIABLE(erase_unit);
+ ASSERT(erase_unit == p_work->erase_unit_idx);
+
+ /* Check if block is in erase unit buffer*/
+ ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left);
+ ASSERT(ret == NRF_SUCCESS);
+ UNUSED_VARIABLE(ret);
+ break;
+ }
+ case NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE:
+ case NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC:
+ {
+ /*Clear last programmed block*/
+ uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks));
+
+ if (p_work->state == NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC)
+ {
+ p_work->erase_unit_dirty_blocks ^= 1u << block_to_program;
+ }
+
+ if (p_work->erase_unit_dirty_blocks == 0)
+ {
+ if (p_work->left_req.blk_count)
+ {
+ /*Load next erase unit*/
+ ret_code_t ret;
+ uint32_t eunit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id,
+ p_work->geometry.blk_size);
+
+ p_work->erase_unit_idx = eunit;
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD;
+
+ ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff,
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE,
+ p_work->erase_unit_idx *
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+ UNUSED_VARIABLE(ret);
+
+ break;
+ }
+
+ /*All blocks are programmed. Call event handler if required.*/
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ if (p_work->ev_handler && !p_work->cache_flushing)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ &p_work->req,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(&p_qspi_dev->block_dev, &ev);
+ }
+
+ p_work->cache_flushing = false;
+ break;
+ }
+
+ /*Get next block to program from program mask*/
+ block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks));
+ uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) +
+ (block_to_program * p_work->geometry.blk_size);
+
+ const void * p_src_address = p_work->p_erase_unit_buff +
+ block_to_program * p_work->geometry.blk_size;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC;
+ ret_code_t ret = nrf_drv_qspi_write(p_src_address,
+ p_work->geometry.blk_size,
+ dst_address);
+ UNUSED_VARIABLE(ret);
+ break;
+ }
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+static void wait_for_idle(nrf_block_dev_qspi_t const * p_qspi_dev)
+{
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+ while (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ __WFI();
+ }
+}
+
+static ret_code_t block_dev_qspi_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+ nrf_drv_qspi_config_t const * p_qspi_cfg = &p_qspi_dev->qspi_bdev_config.qspi_config;
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ if (p_qspi_dev->qspi_bdev_config.block_size % BD_PAGE_PROGRAM_SIZE)
+ {
+ /*Unsupported block size*/
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE % p_qspi_dev->qspi_bdev_config.block_size)
+ {
+ /*Unsupported block size*/
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (m_active_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ ret = nrf_drv_qspi_init(p_qspi_cfg, qspi_handler, (void *)p_blk_dev);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ .opcode = QSPI_STD_CMD_RSTEN,
+ .length = NRF_QSPI_CINSTR_LEN_1B,
+ .io2_level = true,
+ .io3_level = true,
+ .wipwait = true,
+ .wren = true
+ };
+
+ /* Send reset enable */
+ ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ /* Send reset command */
+ cinstr_cfg.opcode = QSPI_STD_CMD_RST;
+ ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ /* Get 3 byte identification value */
+ uint8_t rdid_buf[3] = {0, 0, 0};
+ cinstr_cfg.opcode = QSPI_STD_CMD_READ_ID;
+ cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_4B;
+ ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, rdid_buf);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_serial_flash_params_t const * serial_flash_id = nrf_serial_flash_params_get(rdid_buf);
+
+ if (!serial_flash_id)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (serial_flash_id->erase_size != NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ /* Calculate block device geometry.... */
+ uint32_t blk_size = p_qspi_dev->qspi_bdev_config.block_size;
+ uint32_t blk_count = serial_flash_id->size / p_qspi_dev->qspi_bdev_config.block_size;
+
+ if (!blk_count || (blk_count % BD_BLOCKS_PER_ERASEUNIT(blk_size)))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ p_work->geometry.blk_size = blk_size;
+ p_work->geometry.blk_count = blk_count;
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ p_work->erase_unit_idx = BD_ERASE_UNIT_INVALID_ID;
+ p_work->writeback_mode = (p_qspi_dev->qspi_bdev_config.flags &
+ NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK) != 0;
+ m_active_qspi_dev = p_qspi_dev;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_qspi_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ if (m_active_qspi_dev != p_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ /* Previous asynchronous operation in progress*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_DISABLED;
+ nrf_drv_qspi_uninit();
+
+ memset(p_work, 0, sizeof(nrf_block_dev_qspi_work_t));
+ m_active_qspi_dev = NULL;
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_qspi_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ if (m_active_qspi_dev != p_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ /* Previous asynchronous operation in progress*/
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->left_req = *p_blk;
+ p_work->req = *p_blk;
+ nrf_block_req_t * p_blk_left = &p_work->left_req;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC;
+ ret = nrf_drv_qspi_read(p_blk_left->p_buff,
+ p_blk_left->blk_count * p_work->geometry.blk_size,
+ p_blk_left->blk_id * p_work->geometry.blk_size);
+
+ if (ret != NRF_SUCCESS)
+ {
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ return ret;
+ }
+
+ p_blk_left->p_buff = NULL;
+ p_blk_left->blk_count = 0;
+
+ if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE))
+ {
+ /*Synchronous operation*/
+ wait_for_idle(p_qspi_dev);
+ }
+
+ return ret;
+}
+
+static bool block_dev_qspi_update_eunit(nrf_block_dev_qspi_t const * p_qspi_dev,
+ size_t off,
+ const void * p_src,
+ size_t len)
+{
+ ASSERT((len % sizeof(uint32_t)) == 0)
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ uint32_t * p_dst32 = (uint32_t *)(p_work->p_erase_unit_buff + off);
+ const uint32_t * p_src32 = p_src;
+
+ bool erase_required = false;
+ len /= sizeof(uint32_t);
+
+ /*Do normal copying until erase unit is not required*/
+ do
+ {
+ if (*p_dst32 != *p_src32)
+ {
+ if (*p_dst32 != BD_ERASE_UNIT_ERASE_VAL)
+ {
+ erase_required = true;
+ }
+
+ /*Mark block as dirty*/
+ p_work->erase_unit_dirty_blocks |= 1u << (off / p_work->geometry.blk_size);
+ }
+
+ *p_dst32++ = *p_src32++;
+ off += sizeof(uint32_t);
+ } while (--len);
+
+ return erase_required;
+}
+
+static ret_code_t block_dev_qspi_write_start(nrf_block_dev_qspi_t const * p_qspi_dev)
+{
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ if (!p_work->erase_required)
+ {
+ /*Get first block to program from program mask*/
+ uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks));
+ uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) +
+ (block_to_program * p_work->geometry.blk_size);
+
+ const void * p_src_address = p_work->p_erase_unit_buff +
+ block_to_program * p_work->geometry.blk_size;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC;
+ return nrf_drv_qspi_write(p_src_address,
+ p_work->geometry.blk_size,
+ dst_address);
+ }
+
+ /*Erase is required*/
+ uint32_t address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE;
+ p_work->erase_required = false;
+
+ return nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address);
+}
+
+static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev,
+ nrf_block_req_t * p_blk_left)
+{
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ size_t blk = p_blk_left->blk_id %
+ BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size);
+ size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk;
+ size_t off = p_work->geometry.blk_size * blk;
+
+ if (cnt > p_blk_left->blk_count)
+ {
+ cnt = p_blk_left->blk_count;
+ }
+
+ bool erase_required = block_dev_qspi_update_eunit(p_qspi_dev,
+ off,
+ p_blk_left->p_buff,
+ cnt * p_work->geometry.blk_size);
+ if (erase_required)
+ {
+ p_work->erase_required = true;
+ }
+
+ p_blk_left->blk_count -= cnt;
+ p_blk_left->blk_id += cnt;
+ p_blk_left->p_buff = (uint8_t *)p_blk_left->p_buff + cnt * p_work->geometry.blk_size;
+
+ if (p_work->erase_required)
+ {
+ uint32_t blk_size = p_work->geometry.blk_size;
+ p_work->erase_unit_dirty_blocks |= (1u << BD_BLOCKS_PER_ERASEUNIT(blk_size)) - 1;
+ }
+
+ if (p_work->erase_unit_dirty_blocks == 0 || p_work->writeback_mode)
+ {
+ /*No dirty blocks detected. Write end.*/
+ if (p_work->ev_handler && p_blk_left->blk_count == 0)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ &p_work->req,
+ p_work->p_context
+ };
+
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ p_work->ev_handler(&p_qspi_dev->block_dev, &ev);
+ return NRF_SUCCESS;
+ }
+ }
+
+ return block_dev_qspi_write_start(p_qspi_dev);
+}
+
+static ret_code_t block_dev_qspi_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ if (m_active_qspi_dev != p_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ /* Previous asynchronous operation in progress*/
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->left_req = *p_blk;
+ p_work->req = *p_blk;
+
+ nrf_block_req_t * p_blk_left = &p_work->left_req;
+
+ uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id,
+ p_work->geometry.blk_size);
+
+ /* Check if block is in erase unit buffer*/
+ if (erase_unit == p_work->erase_unit_idx)
+ {
+ ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left);
+ }
+ else
+ {
+ if (p_work->writeback_mode)
+ {
+ ret = block_dev_qspi_write_start(p_qspi_dev);
+ }
+ else
+ {
+ p_work->erase_unit_idx = erase_unit;
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD;
+
+ ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff,
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE,
+ erase_unit * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+ }
+ }
+
+ if (ret != NRF_SUCCESS)
+ {
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ return ret;
+ }
+
+ if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE))
+ {
+ /*Synchronous operation*/
+ wait_for_idle(p_qspi_dev);
+ }
+
+ return ret;
+}
+
+static ret_code_t block_dev_qspi_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ if (!p_work->writeback_mode || p_work->erase_unit_dirty_blocks == 0)
+ {
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = block_dev_qspi_write_start(p_qspi_dev);
+ if (ret == NRF_SUCCESS)
+ {
+ if (p_flushing)
+ {
+ *p_flushing = true;
+ }
+ p_work->cache_flushing = true;
+ }
+
+ return ret;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_qspi_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static nrf_block_dev_geometry_t const * block_dev_qspi_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_qspi_ops = {
+ .init = block_dev_qspi_init,
+ .uninit = block_dev_qspi_uninit,
+ .read_req = block_dev_qspi_read_req,
+ .write_req = block_dev_qspi_write_req,
+ .ioctl = block_dev_qspi_ioctl,
+ .geometry = block_dev_qspi_geometry,
+};
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h
new file mode 100644
index 0000000..f73a729
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_QSPI_H__
+#define NRF_BLOCK_DEV_QSPI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+#include "nrf_drv_qspi.h"
+
+/**@file
+ *
+ * @defgroup nrf_block_dev_qspi QSPI implementation
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ */
+
+/**
+ * @brief QSPI block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_qspi_ops;
+
+/**
+ * @brief QSPI block device internal erase unit buffer size
+ * */
+#define NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE (4096)
+
+/**
+ * @brief Internal Block device state
+ */
+typedef enum {
+ NRF_BLOCK_DEV_QSPI_STATE_DISABLED = 0, /**< QSPI block device state DISABLED */
+ NRF_BLOCK_DEV_QSPI_STATE_IDLE, /**< QSPI block device state IDLE */
+ NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC, /**< QSPI block device state READ_EXEC */
+ NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD, /**< QSPI block device state EUNIT_LOAD */
+ NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE, /**< QSPI block device state WRITE_ERASE */
+ NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC, /**< QSPI block device state WRITE_EXEC */
+} nrf_block_dev_qspi_state_t;
+
+/**
+ * @brief Work structure of QSPI block device
+ */
+typedef struct {
+ volatile nrf_block_dev_qspi_state_t state; //!< QSPI block device state
+
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ void const * p_context; //!< Context handle passed to event handler
+ nrf_block_req_t req; //!< Block READ/WRITE request: original value
+ nrf_block_req_t left_req; //!< Block READ/WRITE request: left value
+
+ bool cache_flushing; //!< QSPI cache flush in progress flag
+ bool writeback_mode; //!< QSPI write-back mode flag
+ bool erase_required; //!< QSPI erase required flag
+ uint32_t erase_unit_idx; //!< QSPI erase unit index
+ uint32_t erase_unit_dirty_blocks; //!< QSPI erase unit dirty blocks mask
+ uint8_t p_erase_unit_buff[NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE]; //!< QSPI erase unit buffer (fixed value)
+} nrf_block_dev_qspi_work_t;
+
+/**
+ * @brief QSPI block device flags*/
+typedef enum {
+ NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK = (1u << 0) //!< Cache write-back mode enable flag
+} nrf_block_dev_qspi_flag_t;
+
+/**
+ * @brief QSPI block device config initializer (@ref nrf_block_dev_qspi_config_t)
+ *
+ * @param blk_size Block size
+ * @param blk_flags Block device flags, @ref nrf_block_dev_qspi_flag_t
+ * @param qspi_drv_config QPSI driver config
+ * */
+#define NRF_BLOCK_DEV_QSPI_CONFIG(blk_size, blk_flags, qspi_drv_config) { \
+ .block_size = (blk_size), \
+ .flags = (blk_flags), \
+ .qspi_config = qspi_drv_config \
+}
+
+/**
+ * @brief QSPI block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ uint32_t flags; //!< QSPI block device flags
+ nrf_drv_qspi_config_t qspi_config; //!< QSPI configuration
+} nrf_block_dev_qspi_config_t;
+
+/**
+ * @brief QSPI block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_qspi_config_t qspi_bdev_config; //!< QSPI block device config
+ nrf_block_dev_qspi_work_t * p_work; //!< QSPI block device work structure
+} nrf_block_dev_qspi_t;
+
+/**
+ * @brief Defines a QSPI block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_qspi_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_QSPI_DEFINE(name, config, info) \
+ static nrf_block_dev_qspi_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_qspi_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_qspi_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .qspi_bdev_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from QSPI block device.
+ *
+ * @param[in] p_blk_qspi QSPI block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_qspi_ops_get(nrf_block_dev_qspi_t const * p_blk_qspi)
+{
+ return &p_blk_qspi->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_QSPI_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c
new file mode 100644
index 0000000..47a8232
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_serial_flash_params.h"
+
+static const nrf_serial_flash_params_t m_sflash_params[] = {
+ { /*MXIC MX25R6435F*/
+ .read_id = { 0xC2, 0x28, 0x17 },
+ .capabilities = 0x00,
+ .size = 8 * 1024 * 1024,
+ .erase_size = 4 * 1024,
+ .program_size = 256,
+ }
+};
+
+nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_id)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(m_sflash_params); ++i)
+ {
+ if (memcmp(m_sflash_params[i].read_id, p_read_id, sizeof(m_sflash_params[i].read_id)) == 0)
+ {
+ return &m_sflash_params[i];
+ }
+ }
+
+ return NULL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h
new file mode 100644
index 0000000..fd02404
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_SERIAL_FLASH_PARAMS_H__
+#define NRF_SERIAL_FLASH_PARAMS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_common.h"
+
+/**@file
+ *
+ * @defgroup nrf_serial_flash_params Serial flash memory parameters
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ */
+
+/**
+ * @brief Serial flash memory parameters
+ * */
+typedef struct {
+ uint8_t read_id[3]; //!< Read identification command (0x9F) result
+ uint8_t capabilities; //!< Serial flash memory capabilities
+ uint32_t size; //!< Serial flash memory size (bytes)
+ uint32_t erase_size; //!< Serial flash memory erase unit size (bytes)
+ uint32_t program_size; //!< Serial flash memory program size (bytes)
+} nrf_serial_flash_params_t;
+
+
+/**
+ * @brief Returns serial flash memory identification descriptor
+ *
+ * @param p_read_params Memory read identification command result
+ *
+ * @return Serial flash memory descriptor (NULL if not found)
+ * */
+nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_params);
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SERIAL_FLASH_PARAMS_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c
new file mode 100644
index 0000000..1acbab9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_block_dev_ram.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+static ret_code_t block_dev_ram_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work;
+
+ /* Calculate block device geometry.... */
+ p_work->geometry.blk_size = p_ram_dev->ram_config.block_size;
+ p_work->geometry.blk_count = p_ram_dev->ram_config.size /
+ p_ram_dev->ram_config.block_size;
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_ram_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ memset(p_work, 0, sizeof(nrf_block_dev_ram_work_t));
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_ram_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk,
+ nrf_block_dev_event_type_t event)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_config_t const * p_ram_config = &p_ram_dev->ram_config;
+ nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work;
+
+ /*Synchronous operation*/
+ uint8_t * p_buff = p_ram_config->p_work_buffer;
+ p_buff += p_blk->blk_id * p_work->geometry.blk_size;
+
+ const void * p_src = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_buff : p_blk->p_buff;
+ void * p_dst = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_blk->p_buff : p_buff;
+
+ memcpy(p_dst, p_src, p_work->geometry.blk_size * p_blk->blk_count);
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ event,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ p_blk,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_ram_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_READ_DONE);
+}
+
+static ret_code_t block_dev_ram_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE);
+}
+
+static ret_code_t block_dev_ram_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+ return NRF_SUCCESS;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_ram_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+static nrf_block_dev_geometry_t const * block_dev_ram_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_ram_ops = {
+ .init = block_dev_ram_init,
+ .uninit = block_dev_ram_uninit,
+ .read_req = block_dev_ram_read_req,
+ .write_req = block_dev_ram_write_req,
+ .ioctl = block_dev_ram_ioctl,
+ .geometry = block_dev_ram_geometry,
+};
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h
new file mode 100644
index 0000000..d8046dc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_RAM_H__
+#define NRF_BLOCK_DEV_RAM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+
+/**@file
+ *
+ * @defgroup nrf_block_dev_ram RAM implementation
+ * @ingroup nrf_block_dev
+ * @{
+
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+/**
+ * @brief RAM block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_ram_ops;
+
+/**
+ * @brief Work structure of RAM block device
+ */
+typedef struct {
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ void const * p_context; //!< Context handle passed to event handler
+} nrf_block_dev_ram_work_t;
+
+
+/**
+ * @brief RAM block device config initializer (@ref nrf_block_dev_ram_config_t)
+ *
+ * @param blk_size Block size
+ * @param buffer RAM work buffer
+ * @param buffer_size RAM work buffer size
+ * */
+#define NRF_BLOCK_DEV_RAM_CONFIG(blk_size, buffer, buffer_size) { \
+ .block_size = (blk_size), \
+ .p_work_buffer = (buffer), \
+ .size = (buffer_size), \
+}
+
+/**
+ * @brief Ram block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ void * p_work_buffer; //!< Ram work buffer
+ size_t size; //!< Ram work buffer size
+} nrf_block_dev_ram_config_t;
+
+/**
+ * @brief Ram block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_ram_config_t ram_config; //!< Ram block device config
+ nrf_block_dev_ram_work_t * p_work; //!< Ram block device work structure
+} nrf_block_dev_ram_t;
+
+/**
+ * @brief Defines a RAM block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_ram_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_RAM_DEFINE(name, config, info) \
+ static nrf_block_dev_ram_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_ram_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_ram_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .ram_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from RAM block device.
+ *
+ * @param[in] p_blk_ram Ram block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_ram_ops_get(nrf_block_dev_ram_t const * p_blk_ram)
+{
+ return &p_blk_ram->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_RAM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c
new file mode 100644
index 0000000..126321f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_block_dev_sdc.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev_sdc
+ * @{
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+
+static volatile sdc_result_t m_last_result;
+
+
+/**
+ * @brief Active SDC block device handle. Only one instance.
+ * */
+static nrf_block_dev_sdc_t const * m_active_sdc_dev;
+
+
+
+static void wait_func(void)
+{
+}
+
+static void sdc_wait()
+{
+ while (app_sdc_busy_check())
+ {
+ wait_func();
+ }
+}
+
+
+static void sdc_handler(sdc_evt_t const * p_event)
+{
+ m_last_result = p_event->result;
+ nrf_block_dev_sdc_t const * p_sdc_dev = m_active_sdc_dev;
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ switch (p_event->type)
+ {
+ case SDC_EVT_INIT:
+ {
+ p_work->geometry.blk_count = app_sdc_info_get()->num_blocks;
+ p_work->geometry.blk_size = SDC_SECTOR_SIZE;
+ if (m_active_sdc_dev->p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ ((p_event->result == SDC_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ NULL,
+ p_work->p_context
+ };
+ p_work->ev_handler(&p_sdc_dev->block_dev, &ev);
+ }
+ }
+ break;
+
+ case SDC_EVT_READ:
+ if (m_active_sdc_dev->p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ ((p_event->result == SDC_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(&p_sdc_dev->block_dev, &ev);
+ }
+ break;
+
+ case SDC_EVT_WRITE:
+ if (m_active_sdc_dev->p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ ((p_event->result == SDC_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(&p_sdc_dev->block_dev, &ev);
+ }
+ break;
+
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ return;
+ }
+}
+
+
+static ret_code_t block_dev_sdc_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ if (p_sdc_dev->sdc_bdev_config.block_size != SDC_SECTOR_SIZE)
+ {
+ /* Unsupported block size. */
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (m_active_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+ m_active_sdc_dev = p_sdc_dev;
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ err_code = app_sdc_init(&p_sdc_dev->sdc_bdev_config.sdc_config, sdc_handler);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (!ev_handler)
+ {
+ /* Synchronous mode - wait for the card. */
+ sdc_wait();
+ err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+ }
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ m_active_sdc_dev = NULL;
+
+ if (ev_handler)
+ {
+ /* Call the user handler with an error status. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_IO_ERROR,
+ NULL,
+ p_work->p_context
+ };
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ if (m_active_sdc_dev != p_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ if (app_sdc_busy_check())
+ {
+ /* Previous asynchronous operation in progress. */
+ return NRF_ERROR_BUSY;
+ }
+
+ ret_code_t err_code = app_sdc_uninit();
+ if (err_code == NRF_SUCCESS)
+ {
+ /* Free the instance on success. */
+ m_active_sdc_dev = NULL;
+ }
+
+ if (p_work->ev_handler)
+ {
+ /* SDC uninitialization is a synchronous operation. Call event handler. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ ((err_code == NRF_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_active_sdc_dev != p_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ if (app_sdc_busy_check())
+ {
+ /* Previous asynchronous operation in progress. */
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->req = *p_blk;
+ err_code = app_sdc_block_read(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (!p_work->ev_handler)
+ {
+ /* Synchronous mode - wait for the card. */
+ sdc_wait();
+ err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+ }
+ }
+
+ if ((p_work->ev_handler) && (err_code != NRF_SUCCESS))
+ {
+ /* Call the user handler with an error status. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_IO_ERROR,
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_active_sdc_dev != p_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ if (app_sdc_busy_check())
+ {
+ /* Previous asynchronous operation in progress. */
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->req = *p_blk;
+ err_code = app_sdc_block_write(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (!p_work->ev_handler)
+ {
+ /* Synchronous mode - wait for the card. */
+ sdc_wait();
+ err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+ }
+ }
+
+ if ((p_work->ev_handler) && (err_code != NRF_SUCCESS))
+ {
+ /* Call the user handler with an error status. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_IO_ERROR,
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+ return NRF_SUCCESS;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_sdc_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static nrf_block_dev_geometry_t const * block_dev_sdc_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t const * p_work = p_sdc_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_sdc_ops = {
+ .init = block_dev_sdc_init,
+ .uninit = block_dev_sdc_uninit,
+ .read_req = block_dev_sdc_read_req,
+ .write_req = block_dev_sdc_write_req,
+ .ioctl = block_dev_sdc_ioctl,
+ .geometry = block_dev_sdc_geometry,
+};
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h
new file mode 100644
index 0000000..cab8032
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_block_dev_sdc SDC implementation
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ */
+
+
+#ifndef NRF_BLOCK_DEV_SDC_H__
+#define NRF_BLOCK_DEV_SDC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+#include "app_sdcard.h"
+
+/**
+ * @brief SDC block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_sdc_ops;
+
+/**
+ * @brief Work structure of SDC block device
+ */
+typedef struct {
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ nrf_block_req_t req; //!< Block READ/WRITE request
+ void const * p_context; //!< Context handle passed to event handler
+} nrf_block_dev_sdc_work_t;
+
+/**
+ * @brief SDC block device config initializer (@ref nrf_block_dev_sdc_config_t)
+ *
+ * @param blk_size Block size
+ * @param sdc_lib_config SDC library config (@ref app_sdc_config_t)
+ * */
+#define NRF_BLOCK_DEV_SDC_CONFIG(blk_size, sdc_lib_config) \
+{ \
+ .block_size = (blk_size), \
+ .sdc_config = sdc_lib_config \
+}
+
+
+/**
+ * @brief SDC block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ app_sdc_config_t sdc_config; //!< SDC library configuration
+} nrf_block_dev_sdc_config_t;
+
+/**
+ * @brief SDC block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_sdc_config_t sdc_bdev_config; //!< SDC block device config
+ nrf_block_dev_sdc_work_t * p_work; //!< SDC block device work structure
+} nrf_block_dev_sdc_t;
+
+/**
+ * @brief Defines a SDC block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_sdc_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_SDC_DEFINE(name, config, info) \
+ static nrf_block_dev_sdc_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_sdc_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_sdc_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .sdc_bdev_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from SDC block device.
+ *
+ * @param[in] p_blk_sdc SDC block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_sdc_ops_get(nrf_block_dev_sdc_t const * p_blk_sdc)
+{
+ return &p_blk_sdc->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_SDC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
new file mode 100644
index 0000000..44b0072
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
@@ -0,0 +1,1238 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_ble.h"
+
+#include <stddef.h>
+#include "sdk_common.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+#include "nrf_sdm.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_bootloader_info.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_hci.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_ble.h"
+#include "nrf_balloc.h"
+#include "nrf_delay.h"
+#include "nrf_dfu_settings.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_ble
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
+
+#define APP_ADV_DATA_HEADER_SIZE 9 /**< Size of encoded advertisement data header (not including device name). */
+#define APP_ADV_DURATION BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising duration in units of 10 milliseconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/
+#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */
+
+#define GATT_HEADER_LEN 3 /**< GATT header length. */
+#define GATT_PAYLOAD(mtu) ((mtu) - GATT_HEADER_LEN) /**< Length of the ATT payload for a given ATT MTU. */
+#define MAX_DFU_PKT_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - GATT_HEADER_LEN) /**< Maximum length (in bytes) of the DFU Packet characteristic (3 bytes are used for the GATT opcode and handle). */
+#define MAX_RESPONSE_LEN 17 /**< Maximum length (in bytes) of the response to a Control Point command. */
+#define RESPONSE_HEADER_LEN 3 /**< The length of the header of a response. I.E. the index of the opcode-specific payload. */
+
+#define DFU_BLE_FLAG_INITIALIZED (1 << 0) /**< Flag to check if the DFU service was initialized by the application.*/
+#define DFU_BLE_FLAG_USE_ADV_NAME (1 << 1) /**< Flag to indicate that advertisement name is to be used. */
+#define DFU_BLE_RESETTING_SOON (1 << 2) /**< Flag to indicate that the device will reset soon. */
+
+#define BLE_OBSERVER_PRIO 2 /**< BLE observer priority. Controls the priority for BLE event handler. */
+
+#if (NRF_DFU_BLE_BUFFERS_OVERRIDE)
+/* If selected, use the override value. */
+#define MAX_DFU_BUFFERS NRF_DFU_BLE_BUFFERS
+#else
+#define MAX_DFU_BUFFERS ((CODE_PAGE_SIZE / MAX_DFU_PKT_LEN) + 1)
+#endif
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS) && (!NRF_SDH_BLE_SERVICE_CHANGED)
+#error NRF_DFU_BLE_REQUIRES_BONDS requires NRF_SDH_BLE_SERVICE_CHANGED. \
+ Please update the SoftDevice BLE stack configuration in sdk_config.h
+#endif
+
+#if (MAX_DFU_PKT_LEN % 4)
+#error Payload length should be a multiple of four. \
+ Payload length is set to NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3.
+#endif
+
+
+static uint32_t ble_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t ble_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const ble_dfu_transport) =
+{
+ .init_func = ble_dfu_transport_init,
+ .close_func = ble_dfu_transport_close,
+};
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+static nrf_dfu_peer_data_t m_peer_data;
+#else
+static nrf_dfu_adv_name_t m_adv_name;
+#endif
+
+static uint32_t m_flags;
+static ble_dfu_t m_dfu; /**< Structure used to identify the Device Firmware Update service. */
+static uint16_t m_pkt_notif_target; /**< Number of packets of firmware data to be received before transmitting the next Packet Receipt Notification to the DFU Controller. */
+static uint16_t m_pkt_notif_target_cnt; /**< Number of packets of firmware data received after sending last Packet Receipt Notification or since the receipt of a @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED event from the DFU service, which ever occurs later.*/
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
+static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
+static nrf_dfu_observer_t m_observer; /**< Observer function called on certain events. */
+
+static ble_gap_conn_params_t const m_gap_conn_params =
+{
+ .min_conn_interval = NRF_DFU_BLE_MIN_CONN_INTERVAL,
+ .max_conn_interval = NRF_DFU_BLE_MAX_CONN_INTERVAL,
+ /* This value is expressed in units of 10 ms, rather than 1 ms. */
+ .conn_sup_timeout = NRF_DFU_BLE_CONN_SUP_TIMEOUT_MS / 10,
+ .slave_latency = 0,
+};
+
+NRF_BALLOC_DEF(m_buffer_pool, MAX_DFU_PKT_LEN, MAX_DFU_BUFFERS);
+
+
+/**@brief Function for the Advertising functionality initialization.
+ *
+ * @details Encodes the required advertising data and passes it to the stack.
+ * The advertising data encoded here is specific for DFU.
+ */
+static uint32_t advertising_init(uint8_t adv_flags, ble_gap_adv_params_t const * const p_adv_params)
+{
+ uint32_t err_code;
+ uint16_t actual_device_name_length = BLE_GAP_ADV_SET_DATA_SIZE_MAX - APP_ADV_DATA_HEADER_SIZE;
+
+ /* This needs to be static because of SoftDevice API requirements. */
+ static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
+
+ ble_gap_adv_data_t m_adv_data =
+ {
+ .adv_data =
+ {
+ .p_data = m_enc_advdata,
+ .len = APP_ADV_DATA_HEADER_SIZE,
+ }
+ };
+
+ /* Encode flags. */
+ m_enc_advdata[0] = 0x2;
+ m_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
+ m_enc_advdata[2] = adv_flags;
+
+ /* Encode 'more available' UUID list. */
+ m_enc_advdata[3] = 0x3;
+ m_enc_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
+ m_enc_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID);
+ m_enc_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID);
+
+ /* Get GAP device name and length. */
+ err_code = sd_ble_gap_device_name_get(&m_enc_advdata[9], &actual_device_name_length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Set GAP device in advertising data.
+ m_enc_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1))
+ m_enc_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
+
+ m_adv_data.adv_data.len += actual_device_name_length;
+
+ return sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, p_adv_params);
+}
+
+
+/**@brief Function for starting advertising.
+ */
+static uint32_t advertising_start(void)
+{
+ uint32_t err_code;
+ uint8_t adv_flag = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
+
+ ble_gap_adv_params_t adv_params =
+ {
+ .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
+ .p_peer_addr = NULL,
+ .filter_policy = BLE_GAP_ADV_FP_ANY,
+ .interval = APP_ADV_INTERVAL,
+ .duration = APP_ADV_DURATION,
+ .primary_phy = BLE_GAP_PHY_1MBPS,
+ };
+
+ NRF_LOG_DEBUG("Advertising...");
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+ ble_gap_irk_t empty_irk = {{0}};
+
+ if (memcmp(m_peer_data.ble_id.id_info.irk, empty_irk.irk, sizeof(ble_gap_irk_t)) == 0)
+ {
+ NRF_LOG_DEBUG("No IRK found, general discovery");
+ }
+ else
+ {
+ NRF_LOG_DEBUG("IRK Found, setting up whitelist");
+
+ adv_flag = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+ adv_params.filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
+
+ ble_gap_addr_t const * const p_gap_addr = &m_peer_data.ble_id.id_addr_info;
+ ble_gap_id_key_t const * const p_gap_id_key = &m_peer_data.ble_id;
+
+ err_code = sd_ble_gap_whitelist_set(&p_gap_addr, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("sd_ble_gap_whitelist_set() returned %s",
+ NRF_LOG_ERROR_STRING_GET(err_code));
+ }
+
+ err_code = sd_ble_gap_device_identities_set(&p_gap_id_key, NULL, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("sd_ble_gap_device_identities_set() returned %s",
+ NRF_LOG_ERROR_STRING_GET(err_code));
+ }
+ }
+#endif /* NRF_DFU_BLE_REQUIRES_BONDS */
+
+ err_code = advertising_init(adv_flag, &adv_params);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ UNUSED_RETURN_VALUE(err_code);
+
+ return sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
+}
+
+
+static bool is_cccd_configured(ble_dfu_t * p_dfu)
+{
+ uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN];
+
+ ble_gatts_value_t gatts_value =
+ {
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = cccd_val_buf
+ };
+
+ /* Check the CCCD Value of DFU Control Point. */
+ uint32_t err_code = sd_ble_gatts_value_get(m_conn_handle,
+ p_dfu->dfu_ctrl_pt_handles.cccd_handle,
+ &gatts_value);
+ VERIFY_SUCCESS(err_code);
+
+ return ble_srv_is_notification_enabled(cccd_val_buf);
+}
+
+
+static ret_code_t response_send(uint8_t * p_buf, uint16_t len)
+{
+ ble_gatts_hvx_params_t hvx_params =
+ {
+ .handle = m_dfu.dfu_ctrl_pt_handles.value_handle,
+ .type = BLE_GATT_HVX_NOTIFICATION,
+ .p_data = (uint8_t *)(p_buf),
+ .p_len = &len,
+ };
+
+ return sd_ble_gatts_hvx(m_conn_handle, &hvx_params);
+}
+
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+static uint32_t service_changed_send(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_DEBUG("Sending Service Changed indication");
+
+ err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
+ m_peer_data.sys_serv_attr,
+ sizeof(m_peer_data.sys_serv_attr),
+ BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
+ NULL,
+ 0,
+ BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gatts_service_changed(m_conn_handle, m_dfu.service_handle, 0xFFFF);
+
+ if ( (err_code == BLE_ERROR_INVALID_CONN_HANDLE)
+ || (err_code == NRF_ERROR_INVALID_STATE)
+ || (err_code == NRF_ERROR_BUSY))
+ {
+ /* These errors can be expected when trying to send a Service Changed indication */
+ /* if the CCCD is not set to indicate. Thus, set the returning error code to success. */
+ NRF_LOG_WARNING("Client did not have the Service Changed indication set to enabled."
+ "Error: 0x%08x", err_code);
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+#endif
+
+
+/**@brief Function for encoding the beginning of a response.
+ *
+ * @param[inout] p_buffer The buffer to encode into.
+ * @param[in] op_code The opcode of the response.
+ * @param[in] result The result of the operation.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_prepare(uint8_t * p_buffer, uint8_t op_code, uint8_t result)
+{
+ ASSERT(p_buffer);
+ p_buffer[0] = NRF_DFU_OP_RESPONSE;
+ p_buffer[1] = op_code;
+ p_buffer[2] = result;
+ return RESPONSE_HEADER_LEN;
+}
+
+
+/**@brief Function for encoding a select object response into a buffer.
+ *
+ * The select object response consists of a maximum object size, a firmware offset, and a CRC value.
+ *
+ * @param[inout] p_buffer The buffer to encode the response into.
+ * @param[in] max_size The maximum object size value to encode.
+ * @param[in] fw_offset The firmware offset value to encode.
+ * @param[in] crc The CRC value to encode.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_select_obj_add(uint8_t * p_buffer,
+ uint32_t max_size,
+ uint32_t fw_offset,
+ uint32_t crc)
+{
+ uint16_t offset = uint32_encode(max_size, &p_buffer[RESPONSE_HEADER_LEN]);
+ offset += uint32_encode(fw_offset, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ offset += uint32_encode(crc, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ return offset;
+}
+
+
+/**@brief Function for encoding a CRC response into a buffer.
+ *
+ * The CRC response consists of a firmware offset and a CRC value.
+ *
+ * @param[inout] p_buffer The buffer to encode the response into.
+ * @param[in] fw_offset The firmware offset value to encode.
+ * @param[in] crc The CRC value to encode.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_crc_add(uint8_t * p_buffer, uint32_t fw_offset, uint32_t crc)
+{
+ uint16_t offset = uint32_encode(fw_offset, &p_buffer[RESPONSE_HEADER_LEN]);
+ offset += uint32_encode(crc, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ return offset;
+}
+
+
+/**@brief Function for appending an extended error code to the response buffer.
+ *
+ * @param[inout] p_buffer The buffer to append the extended error code to.
+ * @param[in] result The error code to append.
+ * @param[in] buf_offset The current length of the buffer.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_ext_err_payload_add(uint8_t * p_buffer, uint8_t result, uint32_t buf_offset)
+{
+ p_buffer[buf_offset] = ext_error_get();
+ (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+ return 1;
+}
+
+
+static void ble_dfu_req_handler_callback(nrf_dfu_response_t * p_res, void * p_context)
+{
+ ASSERT(p_res);
+ ASSERT(p_context);
+
+ uint8_t len = 0;
+ uint8_t buffer[MAX_RESPONSE_LEN] = {0};
+
+ if (p_res->request == NRF_DFU_OP_OBJECT_WRITE)
+ {
+ --m_pkt_notif_target_cnt;
+ if ((m_pkt_notif_target == 0) || (m_pkt_notif_target_cnt && m_pkt_notif_target > 0))
+ {
+ return;
+ }
+
+ /* Reply with a CRC message and reset the packet counter. */
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+
+ p_res->request = NRF_DFU_OP_CRC_GET;
+ }
+
+ len += response_prepare(buffer, p_res->request, p_res->result);
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_WARNING("DFU request %d failed with error: 0x%x", p_res->request, p_res->result);
+
+ if (p_res->result == NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ len += response_ext_err_payload_add(buffer, p_res->result, len);
+ }
+
+ (void) response_send(buffer, len);
+ return;
+ }
+
+ switch (p_res->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ len += response_select_obj_add(buffer,
+ p_res->select.max_size,
+ p_res->select.offset,
+ p_res->select.crc);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ len += response_crc_add(buffer, p_res->write.offset, p_res->write.crc);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ len += response_crc_add(buffer, p_res->crc.offset, p_res->crc.crc);
+ } break;
+
+ default:
+ {
+ // No action.
+ } break;
+ }
+
+ (void) response_send(buffer, len);
+}
+
+
+/**@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 const * p_ble_write_evt)
+{
+ //lint -save -e415 -e416 : Out-of-bounds access on p_ble_write_evt->data
+ nrf_dfu_request_t request =
+ {
+ .request = (nrf_dfu_op_t)(p_ble_write_evt->data[0]),
+ .p_context = p_dfu,
+ .callback.response = ble_dfu_req_handler_callback,
+ };
+
+ switch (request.request)
+ {
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ /* Set object type to read info about */
+ request.select.object_type = p_ble_write_evt->data[1];
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ /* Activity on the current transport. Close all except the current one. */
+ (void) nrf_dfu_transports_close(&ble_dfu_transport);
+
+ /* Reset the packet receipt notification on create object */
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+
+ request.create.object_type = p_ble_write_evt->data[1];
+ request.create.object_size = uint32_decode(&(p_ble_write_evt->data[2]));
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ NRF_LOG_DEBUG("Set receipt notif");
+
+ m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1]));
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+ } break;
+
+ default:
+ break;
+ }
+ //lint -restore : Out-of-bounds access
+
+ return nrf_dfu_req_handler_on_req(&request);
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the
+ * SoftDevice.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static bool on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+
+ ble_gatts_evt_rw_authorize_request_t const * p_authorize_request;
+ ble_gatts_evt_write_t const * p_ble_write_evt;
+
+ p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
+ p_ble_write_evt = &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write);
+
+ 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_authorize_request->request.write.op != BLE_GATTS_OP_WRITE_REQ))
+ {
+ return false;
+ }
+
+ ble_gatts_rw_authorize_reply_params_t auth_reply =
+ {
+ .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
+ .params.write.update = 1,
+ .params.write.offset = p_ble_write_evt->offset,
+ .params.write.len = p_ble_write_evt->len,
+ .params.write.p_data = p_ble_write_evt->data,
+ };
+
+ if (!is_cccd_configured(p_dfu))
+ {
+ /* Send an error response to the peer indicating that the CCCD is improperly configured. */
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
+
+ /* Ignore response of auth reply */
+ (void) sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply);
+ return false;
+ }
+ else
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply);
+ return err_code == NRF_SUCCESS ? true : false;
+ }
+}
+
+
+static void on_flash_write(void * p_buf)
+{
+ NRF_LOG_DEBUG("Freeing buffer %p", p_buf);
+ nrf_balloc_free(&m_buffer_pool, p_buf);
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the 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 const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * const p_write_evt = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_write_evt->handle != p_dfu->dfu_pkt_handles.value_handle)
+ {
+ return;
+ }
+
+ /* Allocate a buffer to receive data. */
+ uint8_t * p_balloc_buf = nrf_balloc_alloc(&m_buffer_pool);
+ if (p_balloc_buf == NULL)
+ {
+ /* Operations are retried by the host; do not give up here. */
+ NRF_LOG_WARNING("cannot allocate memory buffer!");
+ return;
+ }
+
+ NRF_LOG_DEBUG("Buffer %p acquired, len %d (%d)",
+ p_balloc_buf, p_write_evt->len, MAX_DFU_PKT_LEN);
+
+ /* Copy payload into buffer. */
+ memcpy(p_balloc_buf, p_write_evt->data, p_write_evt->len);
+
+ /* Set up the request. */
+ nrf_dfu_request_t request =
+ {
+ .request = NRF_DFU_OP_OBJECT_WRITE,
+ .p_context = p_dfu,
+ .callback =
+ {
+ .response = ble_dfu_req_handler_callback,
+ .write = on_flash_write,
+ }
+ };
+
+ /* Set up the request buffer. */
+ request.write.p_data = p_balloc_buf;
+ request.write.len = p_write_evt->len;
+
+ /* Schedule handling of the request. */
+ ret_code_t rc = nrf_dfu_req_handler_on_req(&request);
+ if (rc != NRF_SUCCESS)
+ {
+ /* The error is logged in nrf_dfu_req_handler_on_req().
+ * Free the buffer.
+ */
+ (void) nrf_balloc_free(&m_buffer_pool, p_balloc_buf);
+ }
+}
+
+
+/**@brief Function for the Application's SoftDevice event handler.
+ *
+ * @param[in] p_ble_evt SoftDevice event.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code;
+ ble_gap_evt_t const * const p_gap = &p_ble_evt->evt.gap_evt;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ {
+ NRF_LOG_DEBUG("Connected");
+
+ m_conn_handle = p_gap->conn_handle;
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+
+ err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_gap_conn_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failure to update connection parameters: 0x%x", err_code);
+ }
+ } break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ {
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ /* Restart advertising so that the DFU Controller can reconnect if possible. */
+ if (!(m_flags & DFU_BLE_RESETTING_SOON))
+ {
+ err_code = advertising_start();
+ APP_ERROR_CHECK(err_code);
+ }
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_DEACTIVATED);
+ }
+ } break;
+
+ case BLE_GATTS_EVT_WRITE:
+ {
+ on_write(&m_dfu, p_ble_evt);
+ } break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
+ {
+ uint16_t const mtu_requested =
+ p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu;
+
+ /* If the requested MTU is smaller than the maximum, we can accept with the given
+ * stack configuration, and the payload is not word-aligned, reply with a smaller MTU
+ * that has a word-aligned payload. This ensures that the length of data we write to
+ * flash is a multiple of the word size.
+ */
+ uint16_t mtu_reply;
+
+ if (mtu_requested < NRF_SDH_BLE_GATT_MAX_MTU_SIZE)
+ {
+ /* Round the payload size down to a multiple of 4 so it is word-aligned. */
+ if (GATT_PAYLOAD(mtu_requested) % 4)
+ {
+ mtu_reply = GATT_PAYLOAD(mtu_requested) - 4;
+ mtu_reply = ALIGN_NUM(4, mtu_reply);
+ /* Add the header len to the MTU. */
+ mtu_reply += GATT_HEADER_LEN;
+ }
+ else
+ {
+ mtu_reply = mtu_requested;
+ }
+ }
+ else
+ {
+ mtu_reply = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+ }
+
+ NRF_LOG_DEBUG("Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (request: %d, reply: %d).",
+ mtu_requested, mtu_reply);
+
+ err_code = sd_ble_gatts_exchange_mtu_reply(m_conn_handle, mtu_reply);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST.");
+
+ ble_gap_data_length_params_t const dlp =
+ {
+ .max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+ .max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+ };
+
+ err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gatts_evt.conn_handle,
+ &dlp, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_DATA_LENGTH_UPDATE (%u, max_rx_time %u).",
+ p_gap->params.data_length_update.effective_params.max_rx_octets,
+ p_gap->params.data_length_update.effective_params.max_rx_time_us);
+ } break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_SEC_PARAMS_REQUEST");
+
+ uint16_t cccd;
+ ble_gatts_value_t gatts_value =
+ {
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = (uint8_t*)&cccd
+ };
+
+ err_code = sd_ble_gatts_value_get(m_conn_handle,
+ BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED,
+ &gatts_value);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_DEBUG("CCCD for service changed is 0x%04x", cccd);
+
+ err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
+ BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
+ NULL,
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_CONN_PARAM_UPDATE");
+
+ ble_gap_conn_params_t const * p_conn =
+ &p_gap->params.conn_param_update.conn_params;
+
+ NRF_LOG_DEBUG("max_conn_interval: %d", p_conn->max_conn_interval);
+ NRF_LOG_DEBUG("min_conn_interval: %d", p_conn->min_conn_interval);
+ NRF_LOG_DEBUG("slave_latency: %d", p_conn->slave_latency);
+ NRF_LOG_DEBUG("conn_sup_timeout: %d", p_conn->conn_sup_timeout);
+ } break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST");
+
+ err_code = sd_ble_gap_conn_param_update(m_conn_handle,
+ &p_gap->params.conn_param_update_request.conn_params);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failure to update connection parameter request: 0x%x", err_code);
+ }
+
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_PHY_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_PHY_UPDATE (RX:%d, TX:%d, status:%d)",
+ p_gap->params.phy_update.rx_phy,
+ p_gap->params.phy_update.tx_phy,
+ p_gap->params.phy_update.status);
+ break;
+ }
+
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_PHY_UPDATE_REQUEST.");
+
+ ble_gap_phys_t const phys =
+ {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+
+ err_code = sd_ble_gap_phy_update(p_gap->conn_handle, &phys);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GATTS_EVT_TIMEOUT:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL)
+ {
+ err_code = sd_ble_gap_disconnect(m_conn_handle,
+ BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ APP_ERROR_CHECK(err_code);
+ }
+ } break;
+
+ case BLE_EVT_USER_MEM_REQUEST:
+ {
+ err_code = sd_ble_user_mem_reply(m_conn_handle, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.authorize_request.type
+ != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
+ {
+ if (on_rw_authorize_req(&m_dfu, p_ble_evt))
+ {
+ err_code = on_ctrl_pt_write(&m_dfu,
+ &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write));
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x", err_code);
+ }
+ }
+ }
+ } break;
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_SEC_INFO_REQUEST");
+
+ ble_gap_enc_info_t * p_enc_info = NULL;
+ ble_gap_irk_t * p_id_info = NULL;
+
+ #if (NRF_DFU_BLE_REQUIRES_BONDS)
+ /* If there is a match in diversifier, then set the correct keys. */
+ if (p_gap->params.sec_info_request.master_id.ediv ==
+ m_peer_data.enc_key.master_id.ediv)
+ {
+ p_enc_info = &m_peer_data.enc_key.enc_info;
+ }
+ p_id_info = &m_peer_data.ble_id.id_info;
+ #endif
+
+ err_code = sd_ble_gap_sec_info_reply(p_gap->conn_handle, p_enc_info, p_id_info, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ {
+ #if (NRF_DFU_BLE_REQUIRES_BONDS)
+ err_code = service_changed_send();
+ #else
+ err_code = sd_ble_gatts_sys_attr_set(p_gap->conn_handle, NULL, 0, 0);
+ #endif
+ APP_ERROR_CHECK(err_code);
+ NRF_LOG_DEBUG("Finished handling conn sec update");
+ } break;
+
+ default:
+ /* No implementation needed. */
+ break;
+ }
+}
+
+
+#if (!NRF_DFU_BLE_REQUIRES_BONDS)
+static uint32_t gap_address_change(void)
+{
+ uint32_t err_code;
+ ble_gap_addr_t addr;
+
+ err_code = sd_ble_gap_addr_get(&addr);
+ VERIFY_SUCCESS(err_code);
+
+ /* Increase the BLE address by one when advertising openly. */
+ addr.addr[0] += 1;
+
+ err_code = sd_ble_gap_addr_set(&addr);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+#endif
+
+
+/**@brief Function for initializing GAP.
+ *
+ * @details This function sets up all necessary GAP (Generic Access Profile) parameters of
+ * the device. It also sets the permissions and appearance.
+ */
+static uint32_t gap_params_init(void)
+{
+ uint32_t err_code;
+ ble_gap_conn_sec_mode_t sec_mode;
+ uint8_t const * device_name;
+ uint32_t name_len;
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+
+#if (!NRF_DFU_BLE_REQUIRES_BONDS)
+
+ err_code = gap_address_change();
+ VERIFY_SUCCESS(err_code);
+
+ if ((m_flags & DFU_BLE_FLAG_USE_ADV_NAME) != 0)
+ {
+ NRF_LOG_DEBUG("Setting adv name: %s, length: %d", m_adv_name.name, m_adv_name.len);
+ device_name = m_adv_name.name;
+ name_len = m_adv_name.len;
+ }
+ else
+#endif
+ {
+ NRF_LOG_DEBUG("Using default advertising name");
+ device_name = (uint8_t const *)(NRF_DFU_BLE_ADV_NAME);
+ name_len = strlen(NRF_DFU_BLE_ADV_NAME);
+ }
+
+ err_code = sd_ble_gap_device_name_set(&sec_mode, device_name, name_len);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gap_ppcp_set(&m_gap_conn_params);
+ return err_code;
+}
+
+
+static uint32_t ble_stack_init()
+{
+ ret_code_t err_code;
+ uint32_t ram_start = 0;
+
+ /* Register as a BLE event observer to receive BLE events. */
+ NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+ err_code = nrf_dfu_mbr_init_sd();
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Setting up vector table: 0x%08x", BOOTLOADER_START_ADDR);
+ err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_START_ADDR);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Enabling SoftDevice.");
+ err_code = nrf_sdh_enable_request();
+ VERIFY_SUCCESS(err_code);
+
+ /* Fetch the start address of the application RAM. */
+ err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Configuring BLE stack.");
+ err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
+ VERIFY_SUCCESS(err_code);
+
+ /* Enable the BLE stack. */
+ NRF_LOG_DEBUG("Enabling the BLE stack.");
+ return nrf_sdh_ble_enable(&ram_start);
+}
+
+
+/**@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 =
+ {
+ .char_props.write_wo_resp = 1,
+ };
+
+ ble_uuid_t char_uuid =
+ {
+ .type = p_dfu->uuid_type,
+ .uuid = BLE_DFU_PKT_CHAR_UUID,
+ };
+
+ ble_gatts_attr_md_t attr_md =
+ {
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .vlen = 1,
+ .write_perm =
+ {
+ .sm = 1,
+ #if NRF_DFU_BLE_REQUIRES_BONDS
+ .lv = 2,
+ #else
+ .lv = 1,
+ #endif
+ }
+ };
+
+ ble_gatts_attr_t attr_char_value =
+ {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &attr_md,
+ .max_len = MAX_DFU_PKT_LEN,
+ };
+
+ 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 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 =
+ {
+ .char_props.write = 1,
+ .char_props.notify = 1,
+ };
+
+ ble_uuid_t char_uuid =
+ {
+ .type = p_dfu->uuid_type,
+ .uuid = BLE_DFU_CTRL_PT_UUID,
+ };
+
+ ble_gatts_attr_md_t attr_md =
+ {
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .wr_auth = 1,
+ .vlen = 1,
+ .write_perm =
+ {
+ .sm = 1,
+ #if NRF_DFU_BLE_REQUIRES_BONDS
+ .lv = 2,
+ #else
+ .lv = 1,
+ #endif
+ },
+ };
+
+ ble_gatts_attr_t attr_char_value =
+ {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &attr_md,
+ .max_len = BLE_GATT_ATT_MTU_DEFAULT,
+ };
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->dfu_ctrl_pt_handles);
+}
+
+
+/**@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.
+ */
+uint32_t ble_dfu_init(ble_dfu_t * p_dfu)
+{
+ ASSERT(p_dfu != NULL);
+
+ ble_uuid_t service_uuid;
+ uint32_t err_code;
+
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &service_uuid,
+ &(p_dfu->service_handle));
+ VERIFY_SUCCESS(err_code);
+
+ ble_uuid128_t const base_uuid128 =
+ {
+ {
+ 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F,
+ 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E
+ }
+ };
+
+ err_code = sd_ble_uuid_vs_add(&base_uuid128, &p_dfu->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = dfu_pkt_char_add(p_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = dfu_ctrl_pt_add(p_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t ble_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_flags & DFU_BLE_FLAG_INITIALIZED)
+ {
+ return err_code;
+ }
+
+ NRF_LOG_DEBUG("Initializing BLE DFU transport");
+
+ m_observer = observer;
+
+ err_code = nrf_balloc_init(&m_buffer_pool);
+ UNUSED_RETURN_VALUE(err_code);
+
+ err_code = ble_stack_init();
+ VERIFY_SUCCESS(err_code);
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+ /* Copy out the peer data if bonds are required */
+ if (nrf_dfu_settings_peer_data_is_valid())
+ {
+ NRF_LOG_DEBUG("Copying peer data");
+
+ err_code = nrf_dfu_settings_peer_data_copy(&m_peer_data);
+ UNUSED_RETURN_VALUE(err_code);
+ }
+ else
+ {
+ APP_ERROR_HANDLER(NRF_ERROR_INTERNAL);
+ }
+#else
+ /* Copy out the new advertisement name when bonds are not required and the name is set. */
+ if (nrf_dfu_settings_adv_name_is_valid())
+ {
+ err_code = nrf_dfu_settings_adv_name_copy(&m_adv_name);
+ UNUSED_RETURN_VALUE(err_code);
+
+ /* Set flags for advertisement name that is to be used */
+ m_flags |= DFU_BLE_FLAG_USE_ADV_NAME;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No advertising name found");
+ }
+#endif
+
+ err_code = gap_params_init();
+ VERIFY_SUCCESS(err_code);
+
+ /* Initialize the Device Firmware Update Service. */
+ err_code = ble_dfu_init(&m_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = advertising_start();
+ VERIFY_SUCCESS(err_code);
+
+ m_flags |= DFU_BLE_FLAG_INITIALIZED;
+
+ NRF_LOG_DEBUG("BLE DFU transport initialized.");
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t ble_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if ((m_flags & DFU_BLE_FLAG_INITIALIZED) && (p_exception != &ble_dfu_transport))
+ {
+ NRF_LOG_DEBUG("Shutting down BLE transport.");
+
+ if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ NRF_LOG_DEBUG("Disconnecting.");
+
+ /* Set flag to prevent advertisement from starting */
+ m_flags |= DFU_BLE_RESETTING_SOON;
+
+ /* Disconnect from the peer. */
+ err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ VERIFY_SUCCESS(err_code);
+
+ /* Wait a bit for the disconnect event to be sent on air. */
+ nrf_delay_ms(200);
+ }
+ else
+ {
+ err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ UNUSED_RETURN_VALUE(err_code);
+ }
+
+ err_code = nrf_sdh_disable_request();
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("BLE transport shut down.");
+ }
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h
new file mode 100644
index 0000000..04d2d55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu_ble DFU BLE Service
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer for <em>Bluetooth</em> low energy.
+ *
+ * @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 the service and characteristics, and is intended to demonstrate
+ * firmware updates over BLE. See @ref lib_dfu_transport_ble "DFU Transport: BLE" for more information on the service and the profile.
+ */
+
+#ifndef NRF_DFU_BLE_H__
+#define NRF_DFU_BLE_H__
+
+#include <stdint.h>
+#include "ble_gatts.h"
+#include "ble.h"
+#include "nrf_dfu_transport.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This is a 16-bit UUID.
+#define BLE_DFU_SERVICE_UUID 0xFE59 //!< UUID of the DFU Service.
+
+// These UUIDs are used with the Nordic base address to create a 128-bit UUID (0x8EC9XXXXF3154F609FB8838830DAEA50).
+#define BLE_DFU_CTRL_PT_UUID 0x0001 //!< UUID of the DFU Control Point.
+#define BLE_DFU_PKT_CHAR_UUID 0x0002 //!< UUID of the DFU Packet Characteristic.
+
+
+/**@brief DFU Service.
+ *
+ * @details This structure contains status information related to the service.
+ */
+typedef struct
+{
+ uint16_t service_handle; /**< Handle of the DFU Service (as provided by the SoftDevice). */
+ uint8_t uuid_type; /**< UUID type assigned to the DFU Service by the 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_dfu_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_BLE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h
new file mode 100644
index 0000000..0377a4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu_svci_bond_sharing Supervisor call interface for bond sharing
+ * @{
+ * @ingroup nrf_dfu
+ * @brief The Supervisor call interface is a thread-safe method to call into the current application or into an external application using a Supervisor instruction.
+ *
+ */
+
+
+#ifndef NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+#define NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+
+#include <stdbool.h>
+#include "nrf_svci.h"
+#include "nrf_svci_async_function.h"
+#include "sdk_config.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_DFU_SVCI_SET_PEER_DATA 2
+#define NRF_DFU_SVCI_SET_ADV_NAME 3
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+
+/**@brief Sets up the async SVCI interface for exchanging peer data like bonding and the system attribute table.
+ *
+ * @details The peer data will be stored in flash by the bootloader. This requires memory management and
+ * handling forwarding of system events and state from the main application to the bootloader.
+ *
+ * @note This is only available in the buttonless DFU that supports bond sharing.
+ */
+NRF_SVCI_ASYNC_FUNC_DECLARE(NRF_DFU_SVCI_SET_PEER_DATA, nrf_dfu_set_peer_data, nrf_dfu_peer_data_t, nrf_dfu_peer_data_state_t);
+
+/**@brief Sets up the async SVCI interface for exchanging advertisement name to use when entering DFU mode.
+ *
+ * @details The advertisement name will be stored in flash by the bootloader. This requires memory management
+ * and handling forwarding of system events and state from the main application to the bootloader.
+ *
+ * @note This is only available in the buttonless DFU that does not support bond sharing.
+ */
+NRF_SVCI_ASYNC_FUNC_DECLARE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t, nrf_dfu_set_adv_name_state_t);
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options
new file mode 100644
index 0000000..a9ed61e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options
@@ -0,0 +1,3 @@
+dfu.Hash.hash max_size:32
+dfu.SignedCommand.signature max_size:64
+dfu.InitCommand.sd_req max_count:16 \ No newline at end of file
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c
new file mode 100644
index 0000000..2396dc6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.6-dev at Wed Dec 13 13:37:53 2017. */
+
+#include "dfu-cc.pb.h"
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+const bool dfu_init_command_is_debug_default = false;
+
+
+const pb_field_t dfu_hash_fields[3] = {
+ PB_FIELD( 1, UENUM , REQUIRED, STATIC , FIRST, dfu_hash_t, hash_type, hash_type, 0),
+ PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, dfu_hash_t, hash, hash_type, 0),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_init_command_fields[10] = {
+ PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, dfu_init_command_t, fw_version, fw_version, 0),
+ PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, hw_version, fw_version, 0),
+ PB_FIELD( 3, UINT32 , REPEATED, STATIC , OTHER, dfu_init_command_t, sd_req, hw_version, 0),
+ PB_FIELD( 4, UENUM , OPTIONAL, STATIC , OTHER, dfu_init_command_t, type, sd_req, 0),
+ PB_FIELD( 5, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, sd_size, type, 0),
+ PB_FIELD( 6, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, bl_size, sd_size, 0),
+ PB_FIELD( 7, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, app_size, bl_size, 0),
+ PB_FIELD( 8, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_init_command_t, hash, app_size, &dfu_hash_fields),
+ PB_FIELD( 9, BOOL , OPTIONAL, STATIC , OTHER, dfu_init_command_t, is_debug, hash, &dfu_init_command_is_debug_default),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_command_fields[3] = {
+ PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, dfu_command_t, op_code, op_code, 0),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_command_t, init, op_code, &dfu_init_command_fields),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_signed_command_fields[4] = {
+ PB_FIELD( 1, MESSAGE , REQUIRED, STATIC , FIRST, dfu_signed_command_t, command, command, &dfu_command_fields),
+ PB_FIELD( 2, UENUM , REQUIRED, STATIC , OTHER, dfu_signed_command_t, signature_type, command, 0),
+ PB_FIELD( 3, BYTES , REQUIRED, STATIC , OTHER, dfu_signed_command_t, signature, signature_type, 0),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_packet_fields[3] = {
+ PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, dfu_packet_t, command, command, &dfu_command_fields),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_packet_t, signed_command, command, &dfu_signed_command_fields),
+ PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 65536 && pb_membersize(dfu_command_t, init) < 65536 && pb_membersize(dfu_signed_command_t, command) < 65536 && pb_membersize(dfu_packet_t, command) < 65536 && pb_membersize(dfu_packet_t, signed_command) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_command_dfu_signed_command_dfu_packet)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 256 && pb_membersize(dfu_command_t, init) < 256 && pb_membersize(dfu_signed_command_t, command) < 256 && pb_membersize(dfu_packet_t, command) < 256 && pb_membersize(dfu_packet_t, signed_command) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_command_dfu_signed_command_dfu_packet)
+#endif
+
+
+/* @@protoc_insertion_point(eof) */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h
new file mode 100644
index 0000000..fae43c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.6-dev at Wed Dec 13 13:37:53 2017. */
+
+#ifndef PB_DFU_CC_PB_H_INCLUDED
+#define PB_DFU_CC_PB_H_INCLUDED
+#include <pb.h>
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enum definitions */
+typedef enum
+{
+ DFU_FW_TYPE_APPLICATION = 0,
+ DFU_FW_TYPE_SOFTDEVICE = 1,
+ DFU_FW_TYPE_BOOTLOADER = 2,
+ DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER = 3
+} dfu_fw_type_t;
+#define DFU_FW_TYPE_MIN DFU_FW_TYPE_APPLICATION
+#define DFU_FW_TYPE_MAX DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER
+#define DFU_FW_TYPE_ARRAYSIZE ((dfu_fw_type_t)(DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER+1))
+
+typedef enum
+{
+ DFU_HASH_TYPE_NO_HASH = 0,
+ DFU_HASH_TYPE_CRC = 1,
+ DFU_HASH_TYPE_SHA128 = 2,
+ DFU_HASH_TYPE_SHA256 = 3,
+ DFU_HASH_TYPE_SHA512 = 4
+} dfu_hash_type_t;
+#define DFU_HASH_TYPE_MIN DFU_HASH_TYPE_NO_HASH
+#define DFU_HASH_TYPE_MAX DFU_HASH_TYPE_SHA512
+#define DFU_HASH_TYPE_ARRAYSIZE ((dfu_hash_type_t)(DFU_HASH_TYPE_SHA512+1))
+
+typedef enum
+{
+ DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256 = 0,
+ DFU_SIGNATURE_TYPE_ED25519 = 1
+} dfu_signature_type_t;
+#define DFU_SIGNATURE_TYPE_MIN DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256
+#define DFU_SIGNATURE_TYPE_MAX DFU_SIGNATURE_TYPE_ED25519
+#define DFU_SIGNATURE_TYPE_ARRAYSIZE ((dfu_signature_type_t)(DFU_SIGNATURE_TYPE_ED25519+1))
+
+typedef enum
+{
+ DFU_COMMAND_OP_CODE_INIT = 1
+} dfu_command_op_code_t;
+#define DFU_COMMAND_OP_CODE_MIN DFU_COMMAND_OP_CODE_INIT
+#define DFU_COMMAND_OP_CODE_MAX DFU_COMMAND_OP_CODE_INIT
+#define DFU_COMMAND_OP_CODE_ARRAYSIZE ((dfu_command_op_code_t)(DFU_COMMAND_OP_CODE_INIT+1))
+
+/* Struct definitions */
+typedef PB_BYTES_ARRAY_T(32) dfu_hash_hash_t;
+typedef struct {
+ dfu_hash_type_t hash_type;
+ dfu_hash_hash_t hash;
+/* @@protoc_insertion_point(struct:dfu_hash_t) */
+} dfu_hash_t;
+
+typedef struct {
+ bool has_fw_version;
+ uint32_t fw_version;
+ bool has_hw_version;
+ uint32_t hw_version;
+ pb_size_t sd_req_count;
+ uint32_t sd_req[16];
+ bool has_type;
+ dfu_fw_type_t type;
+ bool has_sd_size;
+ uint32_t sd_size;
+ bool has_bl_size;
+ uint32_t bl_size;
+ bool has_app_size;
+ uint32_t app_size;
+ bool has_hash;
+ dfu_hash_t hash;
+ bool has_is_debug;
+ bool is_debug;
+/* @@protoc_insertion_point(struct:dfu_init_command_t) */
+} dfu_init_command_t;
+
+typedef struct {
+ bool has_op_code;
+ dfu_command_op_code_t op_code;
+ bool has_init;
+ dfu_init_command_t init;
+/* @@protoc_insertion_point(struct:dfu_command_t) */
+} dfu_command_t;
+
+typedef PB_BYTES_ARRAY_T(64) dfu_signed_command_signature_t;
+typedef struct {
+ dfu_command_t command;
+ dfu_signature_type_t signature_type;
+ dfu_signed_command_signature_t signature;
+/* @@protoc_insertion_point(struct:dfu_signed_command_t) */
+} dfu_signed_command_t;
+
+typedef struct {
+ bool has_command;
+ dfu_command_t command;
+ bool has_signed_command;
+ dfu_signed_command_t signed_command;
+/* @@protoc_insertion_point(struct:dfu_packet_t) */
+} dfu_packet_t;
+
+/* Default values for struct fields */
+extern const bool dfu_init_command_is_debug_default;
+
+/* Initializer values for message structs */
+#define DFU_HASH_INIT_DEFAULT {(dfu_hash_type_t)0, {0, {0}}}
+#define DFU_INIT_COMMAND_INIT_DEFAULT {false, 0, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_DEFAULT, false, false}
+#define DFU_COMMAND_INIT_DEFAULT {false, (dfu_command_op_code_t)0, false, DFU_INIT_COMMAND_INIT_DEFAULT}
+#define DFU_SIGNED_COMMAND_INIT_DEFAULT {DFU_COMMAND_INIT_DEFAULT, (dfu_signature_type_t)0, {0, {0}}}
+#define DFU_PACKET_INIT_DEFAULT {false, DFU_COMMAND_INIT_DEFAULT, false, DFU_SIGNED_COMMAND_INIT_DEFAULT}
+#define DFU_HASH_INIT_ZERO {(dfu_hash_type_t)0, {0, {0}}}
+#define DFU_INIT_COMMAND_INIT_ZERO {false, 0, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_ZERO, false, 0}
+#define DFU_COMMAND_INIT_ZERO {false, (dfu_command_op_code_t)0, false, DFU_INIT_COMMAND_INIT_ZERO}
+#define DFU_SIGNED_COMMAND_INIT_ZERO {DFU_COMMAND_INIT_ZERO, (dfu_signature_type_t)0, {0, {0}}}
+#define DFU_PACKET_INIT_ZERO {false, DFU_COMMAND_INIT_ZERO, false, DFU_SIGNED_COMMAND_INIT_ZERO}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define DFU_HASH_HASH_TYPE_TAG 1
+#define DFU_HASH_HASH_TAG 2
+#define DFU_INIT_COMMAND_FW_VERSION_TAG 1
+#define DFU_INIT_COMMAND_HW_VERSION_TAG 2
+#define DFU_INIT_COMMAND_SD_REQ_TAG 3
+#define DFU_INIT_COMMAND_TYPE_TAG 4
+#define DFU_INIT_COMMAND_SD_SIZE_TAG 5
+#define DFU_INIT_COMMAND_BL_SIZE_TAG 6
+#define DFU_INIT_COMMAND_APP_SIZE_TAG 7
+#define DFU_INIT_COMMAND_HASH_TAG 8
+#define DFU_INIT_COMMAND_IS_DEBUG_TAG 9
+#define DFU_COMMAND_OP_CODE_TAG 1
+#define DFU_COMMAND_INIT_TAG 2
+#define DFU_SIGNED_COMMAND_COMMAND_TAG 1
+#define DFU_SIGNED_COMMAND_SIGNATURE_TYPE_TAG 2
+#define DFU_SIGNED_COMMAND_SIGNATURE_TAG 3
+#define DFU_PACKET_COMMAND_TAG 1
+#define DFU_PACKET_SIGNED_COMMAND_TAG 2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t dfu_hash_fields[3];
+extern const pb_field_t dfu_init_command_fields[10];
+extern const pb_field_t dfu_command_fields[3];
+extern const pb_field_t dfu_signed_command_fields[4];
+extern const pb_field_t dfu_packet_fields[3];
+
+/* Maximum encoded size of messages (where known) */
+#define DFU_HASH_SIZE 36
+#define DFU_INIT_COMMAND_SIZE 168
+#define DFU_COMMAND_SIZE 173
+#define DFU_SIGNED_COMMAND_SIZE 244
+#define DFU_PACKET_SIZE 423
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define DFU_CC_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto
new file mode 100644
index 0000000..69f9680
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto
@@ -0,0 +1,66 @@
+package dfu;
+
+// Version 0.1
+
+enum FwType {
+ APPLICATION = 0; // default, compatible with proto3
+ SOFTDEVICE = 1;
+ BOOTLOADER = 2;
+ SOFTDEVICE_BOOTLOADER = 3;
+}
+
+enum HashType {
+ NO_HASH = 0;
+ CRC = 1;
+ SHA128 = 2;
+ SHA256 = 3;
+ SHA512 = 4;
+}
+
+message Hash {
+ required HashType hash_type = 1;
+ required bytes hash = 2;
+}
+
+// Commands data
+message InitCommand {
+ optional uint32 fw_version = 1;
+ optional uint32 hw_version = 2;
+ repeated uint32 sd_req = 3 [packed = true]; // packed option is default in proto3
+ optional FwType type = 4;
+
+ optional uint32 sd_size = 5;
+ optional uint32 bl_size = 6;
+ optional uint32 app_size = 7;
+
+ optional Hash hash = 8;
+
+ optional bool is_debug = 9 [default = false];
+}
+
+// Command type
+message Command {
+ enum OpCode {
+ INIT = 1;
+ }
+ optional OpCode op_code = 1;
+ optional InitCommand init = 2;
+}
+
+// Signed command types
+enum SignatureType {
+ ECDSA_P256_SHA256 = 0;
+ ED25519 = 1;
+}
+
+message SignedCommand {
+ required Command command = 1;
+ required SignatureType signature_type = 2;
+ required bytes signature = 3;
+}
+
+// Parent packet type
+message Packet {
+ optional Command command = 1;
+ optional SignedCommand signed_command = 2;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c
new file mode 100644
index 0000000..f2c9796
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu.h"
+
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_req_handler.h"
+#include "app_timer.h"
+#include "nrf_log.h"
+
+static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
+
+
+
+/**
+ * @brief This function calls the user's observer (@ref m_observer) after it is done handling the event.
+ */
+static void dfu_observer(nrf_dfu_evt_type_t event)
+{
+ switch (event)
+ {
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ {
+#ifndef NRF_DFU_NO_TRANSPORT
+ UNUSED_RETURN_VALUE(nrf_dfu_transports_close(NULL));
+#endif
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Call user's observer if present. */
+ if (m_user_observer)
+ {
+ m_user_observer(event);
+ }
+}
+
+
+
+uint32_t nrf_dfu_init(nrf_dfu_observer_t observer)
+{
+ uint32_t ret_val;
+
+ m_user_observer = observer;
+
+ NRF_LOG_INFO("Entering DFU mode.");
+
+ dfu_observer(NRF_DFU_EVT_DFU_INITIALIZED);
+
+ // Initializing transports
+ ret_val = nrf_dfu_transports_init(dfu_observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not initalize DFU transport: 0x%08x", ret_val);
+ return ret_val;
+ }
+
+ ret_val = nrf_dfu_req_handler_init(dfu_observer);
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h
new file mode 100644
index 0000000..34d7aee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu DFU modules
+ * @{
+ * @ingroup nrf_bootloader
+ * @brief Modules providing Device Firmware Update (DFU) functionality.
+ *
+ * The DFU module, in combination with the @ref nrf_bootloader module,
+ * can be used to implement a bootloader that supports Device Firmware Updates.
+ */
+
+#ifndef NRF_DFU_H__
+#define NRF_DFU_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_DFU_SCHED_EVENT_DATA_SIZE (sizeof(nrf_dfu_request_t))
+
+
+/** @brief Function for initializing a DFU operation.
+ *
+ * This function initializes a DFU operation and any transports that are registered
+ * in the system.
+ *
+ * @param[in] observer Function for receiving DFU notifications.
+ *
+ * @retval NRF_SUCCESS If the DFU operation was successfully initialized.
+ */
+uint32_t nrf_dfu_init(nrf_dfu_observer_t observer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c
new file mode 100644
index 0000000..c4e047a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_flash.h"
+#include "nrf_dfu_types.h"
+
+#include "nrf_fstorage.h"
+#include "nrf_fstorage_sd.h"
+#include "nrf_fstorage_nvmc.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_flash
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+void dfu_fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);
+
+
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_fs) =
+{
+ .evt_handler = dfu_fstorage_evt_handler,
+ .start_addr = MBR_SIZE,
+ .end_addr = BOOTLOADER_SETTINGS_ADDRESS + BOOTLOADER_SETTINGS_PAGE_SIZE
+};
+
+static uint32_t m_flash_operations_pending;
+
+void dfu_fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
+{
+ if (NRF_LOG_ENABLED && (m_flash_operations_pending > 0))
+ {
+ m_flash_operations_pending--;
+ }
+
+ if (p_evt->result == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Flash %s success: addr=%p, pending %d",
+ (p_evt->id == NRF_FSTORAGE_EVT_WRITE_RESULT) ? "write" : "erase",
+ p_evt->addr, m_flash_operations_pending);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Flash %s failed (0x%x): addr=%p, len=0x%x bytes, pending %d",
+ (p_evt->id == NRF_FSTORAGE_EVT_WRITE_RESULT) ? "write" : "erase",
+ p_evt->result, p_evt->addr, p_evt->len, m_flash_operations_pending);
+ }
+
+ if (p_evt->p_param)
+ {
+ //lint -save -e611 (Suspicious cast)
+ ((nrf_dfu_flash_callback_t)(p_evt->p_param))((void*)p_evt->p_src);
+ //lint -restore
+ }
+}
+
+
+ret_code_t nrf_dfu_flash_init(bool sd_irq_initialized)
+{
+ nrf_fstorage_api_t * p_api_impl;
+
+ /* Setup the desired API implementation. */
+#ifdef BLE_STACK_SUPPORT_REQD
+ if (sd_irq_initialized)
+ {
+ NRF_LOG_DEBUG("Initializing nrf_fstorage_sd backend.");
+ p_api_impl = &nrf_fstorage_sd;
+ }
+ else
+#endif
+ {
+ NRF_LOG_DEBUG("Initializing nrf_fstorage_nvmc backend.");
+ p_api_impl = &nrf_fstorage_nvmc;
+ }
+
+ return nrf_fstorage_init(&m_fs, p_api_impl, NULL);
+}
+
+
+ret_code_t nrf_dfu_flash_store(uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t rc;
+
+ NRF_LOG_DEBUG("nrf_fstorage_write(addr=%p, src=%p, len=%d bytes), queue usage: %d",
+ dest, p_src, len, m_flash_operations_pending);
+
+ //lint -save -e611 (Suspicious cast)
+ rc = nrf_fstorage_write(&m_fs, dest, p_src, len, (void *)callback);
+ //lint -restore
+
+ if ((NRF_LOG_ENABLED) && (rc == NRF_SUCCESS))
+ {
+ m_flash_operations_pending++;
+ }
+ else
+ {
+ NRF_LOG_WARNING("nrf_fstorage_write() failed with error 0x%x.", rc);
+ }
+
+ return rc;
+}
+
+
+ret_code_t nrf_dfu_flash_erase(uint32_t page_addr,
+ uint32_t num_pages,
+ nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t rc;
+
+ NRF_LOG_DEBUG("nrf_fstorage_erase(addr=0x%p, len=%d pages), queue usage: %d",
+ page_addr, num_pages, m_flash_operations_pending);
+
+ //lint -save -e611 (Suspicious cast)
+ rc = nrf_fstorage_erase(&m_fs, page_addr, num_pages, (void *)callback);
+ //lint -restore
+
+ if ((NRF_LOG_ENABLED) && (rc == NRF_SUCCESS))
+ {
+ m_flash_operations_pending++;
+ }
+ else
+ {
+ NRF_LOG_WARNING("nrf_fstorage_erase() failed with error 0x%x.", rc);
+ }
+
+ return rc;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h
new file mode 100644
index 0000000..fb14610
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_flash Flash operations
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_FLASH_H__
+#define NRF_DFU_FLASH_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief nrf_fstorage event handler function for DFU fstorage operations.
+ *
+ * This function will be called after a flash operation has completed.
+ */
+typedef void (*nrf_dfu_flash_callback_t)(void * p_buf);
+
+
+/**@brief Function for initializing the flash module.
+ *
+ * Depending on whether or not the SoftDevice is present and its IRQ have been initialized,
+ * this function initializes the correct @ref nrf_fstorage backend.
+ *
+ * @param[in] sd_irq_initialized Whether or not the SoftDevice IRQ have been initialized.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ */
+ret_code_t nrf_dfu_flash_init(bool sd_irq_initialized);
+
+
+/**@brief Function for storing data to flash.
+ *
+ * This functions is asynchronous when the SoftDevice is enabled and synchronous when
+ * the SoftDevice is not present or disabled. In both cases, if a callback function is provided,
+ * it will be called when the operation has completed.
+ *
+ * @note The content of @p p_src should be kept in memory until the operation has completed.
+ *
+ * @param[in] dest The address where the data should be stored.
+ * @param[in] p_src Pointer to the address where the data should be copied from.
+ * This address can be in flash or RAM.
+ * @param[in] len The number of bytes to be copied from @p p_src to @p dest.
+ * @param[in] callback Callback function.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_STATE If nrf_dfu_flash is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR If @p p_src or @p dest is not word-aligned.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero.
+ * @retval NRF_ERROR_NULL If @p p_src is NULL.
+ * @retval NRF_ERROR_NO_MEM If nrf_fstorage is out of memory.
+ */
+ret_code_t nrf_dfu_flash_store(uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ nrf_dfu_flash_callback_t callback);
+
+
+/**@brief Function for erasing data from flash.
+ *
+ * This functions is asynchronous when the SoftDevice is enabled and synchronous when
+ * the SoftDevice is not present or disabled. In both cases, if a callback function is provided,
+ * it will be called when the operation has completed.
+ *
+ * @param[in] page_addr The address of the first flash page to be deleted.
+ * @param[in] num_pages The number of flash pages to be deleted.
+ * @param[in] callback Callback function.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_STATE If nrf_dfu_flash is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR If @p page_addr is not aligned to a page boundary or the
+ * operation would go beyond the flash memory boundaries.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p num_pages is zero.
+ * @retval NRF_ERROR_NULL If @p page_addr is NULL.
+ * @retval NRF_ERROR_NO_MEM If the queue of nrf_fstorage is full.
+ */
+ret_code_t nrf_dfu_flash_erase(uint32_t page_addr, uint32_t num_pages, nrf_dfu_flash_callback_t callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // NRF_DFU_FLASH_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c
new file mode 100644
index 0000000..ba42123
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_handling_error.h"
+
+#include "nrf_log.h"
+#include "nrf_dfu_req_handler.h"
+
+static nrf_dfu_ext_error_code_t m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR;
+
+nrf_dfu_result_t ext_error_set(nrf_dfu_ext_error_code_t error_code)
+{
+ m_last_error = error_code;
+
+ return NRF_DFU_RES_CODE_EXT_ERROR;
+}
+
+nrf_dfu_ext_error_code_t ext_error_get()
+{
+ nrf_dfu_ext_error_code_t last_error = m_last_error;
+ m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR;
+
+ return last_error;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h
new file mode 100644
index 0000000..5a459e9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /**@file
+ *
+ * @defgroup nrf_dfu_rescodes DFU result codes
+ * @{
+ * @ingroup sdk_nrf_dfu_transport
+ * @brief When the DFU controller sends requests to the DFU bootloader on
+ * the DFU target, the DFU bootloader answers with any of these result codes.
+ */
+
+
+#ifndef DFU_HANDLING_ERROR_H__
+#define DFU_HANDLING_ERROR_H__
+
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**@brief DFU request extended result codes.
+ *
+ * @details When an event returns @ref NRF_DFU_RES_CODE_EXT_ERROR, it also stores an extended error code.
+ * The transport layer can then send the extended error code together with the error code to give
+ * the controller additional information about the cause of the error.
+ */
+typedef enum
+{
+ NRF_DFU_EXT_ERROR_NO_ERROR = 0x00, /**< No extended error code has been set. This error indicates an implementation problem. */
+ NRF_DFU_EXT_ERROR_INVALID_ERROR_CODE = 0x01, /**< Invalid error code. This error code should never be used outside of development. */
+ NRF_DFU_EXT_ERROR_WRONG_COMMAND_FORMAT = 0x02, /**< The format of the command was incorrect. This error code is not used in the
+ current implementation, because @ref NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED
+ and @ref NRF_DFU_RES_CODE_INVALID_PARAMETER cover all
+ possible format errors. */
+ NRF_DFU_EXT_ERROR_UNKNOWN_COMMAND = 0x03, /**< The command was successfully parsed, but it is not supported or unknown. */
+ NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID = 0x04, /**< The init command is invalid. The init packet either has
+ an invalid update type or it is missing required fields for the update type
+ (for example, the init packet for a SoftDevice update is missing the SoftDevice size field). */
+ NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE = 0x05, /**< The firmware version is too low. For an application, the version must be greater than
+ the current application. For a bootloader, it must be greater than or equal
+ to the current version. This requirement prevents downgrade attacks.*/
+ NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE = 0x06, /**< The hardware version of the device does not match the required
+ hardware version for the update. */
+ NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE = 0x07, /**< The array of supported SoftDevices for the update does not contain
+ the FWID of the current SoftDevice. */
+ NRF_DFU_EXT_ERROR_SIGNATURE_MISSING = 0x08, /**< The init packet does not contain a signature. This error code is not used in the
+ current implementation, because init packets without a signature
+ are regarded as invalid. */
+ NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE = 0x09, /**< The hash type that is specified by the init packet is not supported by the DFU bootloader. */
+ NRF_DFU_EXT_ERROR_HASH_FAILED = 0x0A, /**< The hash of the firmware image cannot be calculated. */
+ NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE = 0x0B, /**< The type of the signature is unknown or not supported by the DFU bootloader. */
+ NRF_DFU_EXT_ERROR_VERIFICATION_FAILED = 0x0C, /**< The hash of the received firmware image does not match the hash in the init packet. */
+ NRF_DFU_EXT_ERROR_INSUFFICIENT_SPACE = 0x0D, /**< The available space on the device is insufficient to hold the firmware. */
+} nrf_dfu_ext_error_code_t;
+
+
+/**@brief Function for setting an extended error code that can be retrieved later.
+ *
+ * @details When an extended error occurs in the DFU process, this function can be used to store the error.
+ *
+ * @param error_code The error code to store.
+ *
+ * @retval NRF_DFU_RES_CODE_EXT_ERROR
+ */
+nrf_dfu_result_t ext_error_set(nrf_dfu_ext_error_code_t error_code);
+
+/**@brief Function for getting the most recent extended error code.
+ *
+ * @details This function is used by the transport layer to fetch the most recent extended error code.
+ *
+ * @return The most recent error code. If the function is called again before a new error occurs, @ref NRF_DFU_EXT_ERROR_NO_ERROR is returned.
+ */
+nrf_dfu_ext_error_code_t ext_error_get( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DFU_HANDLING_ERROR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c
new file mode 100644
index 0000000..974a466
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_mbr.h"
+#include "nrf_mbr.h"
+#include "nrf_dfu_types.h"
+#include "nrf_log.h"
+#include "nrf_bootloader_info.h"
+
+#define MBR_IRQ_FORWARD_ADDRESS_ADDRESS (0x20000000) //!< The address of the variable that decides where the MBR forwards interrupts
+
+uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len)
+{
+ uint32_t ret_val;
+ uint32_t const len_words = len / sizeof(uint32_t);
+
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_COPY_BL,
+ .params.copy_bl.bl_src = p_src,
+ .params.copy_bl.bl_len = len_words
+ };
+
+ ret_val = sd_mbr_command(&command);
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_mbr_init_sd(void)
+{
+ uint32_t ret_val;
+
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_INIT_SD
+ };
+
+ ret_val = sd_mbr_command(&command);
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_mbr_irq_forward_address_set(void)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_PARAM;
+ uint32_t address = MBR_SIZE;
+
+ NRF_LOG_DEBUG("running irq table set");
+
+#ifndef BLE_STACK_SUPPORT_REQD
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
+ .params.irq_forward_address_set.address = address,
+ };
+
+ ret_val = sd_mbr_command(&command);
+#endif
+
+ if (ret_val == NRF_ERROR_INVALID_PARAM)
+ {
+ // Manually set the forward address if this MBR doesn't have the command.
+ *(uint32_t *)(MBR_IRQ_FORWARD_ADDRESS_ADDRESS) = address;
+
+ ret_val = NRF_SUCCESS;
+ }
+
+ NRF_LOG_DEBUG("After running irq table set");
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h
new file mode 100644
index 0000000..2fcd1b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_mbr MBR functions
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_MBR_H__
+#define NRF_DFU_MBR_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for copying the bootloader using an MBR command.
+ *
+ * @param[in] p_src Source address of the bootloader data to copy.
+ * @param[in] len Length of the data to copy in bytes.
+ *
+ * @return This function will return only if the command request could not be run.
+ * See @ref sd_mbr_command_copy_bl_t for possible return values.
+ */
+uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len);
+
+
+/** @brief Function for initializing the SoftDevice using an MBR command.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice was initialized successfully.
+ * Any other return value indicates that the SoftDevice
+ * could not be initialized.
+ */
+uint32_t nrf_dfu_mbr_init_sd(void);
+
+
+/** @brief Function for setting the address of the IRQ table to the app's using an MBR command.
+ *
+ * @retval NRF_SUCCESS If the address of the new irq table was set. Any other
+ * return value indicates that the address could not be set.
+ */
+uint32_t nrf_dfu_mbr_irq_forward_address_set(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_MBR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c
new file mode 100644
index 0000000..6dfb1cc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c
@@ -0,0 +1,855 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "nrf_dfu.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_fstorage.h"
+#include "nrf_bootloader_info.h"
+#include "app_util.h"
+#include "pb.h"
+#include "pb_common.h"
+#include "pb_decode.h"
+#include "dfu-cc.pb.h"
+#include "crc32.h"
+#include "app_scheduler.h"
+#include "sdk_macros.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "nrf_dfu_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_req_handler
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_DFU_PROTOCOL_VERSION (0x01)
+
+
+STATIC_ASSERT(DFU_SIGNED_COMMAND_SIZE <= INIT_COMMAND_MAX_SIZE);
+
+static uint32_t m_firmware_start_addr; /**< Start address of the current firmware image. */
+static uint32_t m_firmware_size_req; /**< The size of the entire firmware image. Defined by the init command. */
+
+static nrf_dfu_observer_t m_observer;
+
+
+static void on_dfu_complete(nrf_fstorage_evt_t * p_evt)
+{
+ UNUSED_PARAMETER(p_evt);
+
+ NRF_LOG_DEBUG("All flash operations have completed. DFU completed.");
+
+ m_observer(NRF_DFU_EVT_DFU_COMPLETED);
+}
+
+
+static nrf_dfu_result_t ext_err_code_handle(nrf_dfu_result_t ret_val)
+{
+ if (ret_val < NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ return ret_val;
+ }
+ else
+ {
+ nrf_dfu_ext_error_code_t ext_err =
+ (nrf_dfu_ext_error_code_t)((uint8_t)ret_val - (uint8_t)NRF_DFU_RES_CODE_EXT_ERROR);
+ return ext_error_set(ext_err);
+ }
+}
+
+
+static void on_protocol_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_PROTOCOL_VERSION");
+
+ if (NRF_DFU_PROTOCOL_VERSION_MSG)
+ {
+ p_res->protocol.version = NRF_DFU_PROTOCOL_VERSION;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("NRF_DFU_OP_PROTOCOL_VERSION disabled.");
+ p_res->result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ }
+}
+
+
+static void on_hw_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_HARDWARE_VERSION");
+
+ p_res->hardware.part = NRF_FICR->INFO.PART;
+ p_res->hardware.variant = NRF_FICR->INFO.VARIANT;
+
+ /* FICR values are in Kilobytes, we report them in bytes. */
+ p_res->hardware.memory.ram_size = NRF_FICR->INFO.RAM * 1024;
+ p_res->hardware.memory.rom_size = NRF_FICR->INFO.FLASH * 1024;
+ p_res->hardware.memory.rom_page_size = NRF_FICR->CODEPAGESIZE;
+}
+
+
+static void on_fw_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_FIRMWARE_VERSION");
+ NRF_LOG_DEBUG("Firmware image requested: %d", p_req->firmware.image_number);
+
+ if (NRF_DFU_PROTOCOL_FW_VERSION_MSG)
+ {
+ uint8_t fw_count = 1;
+
+ if (SD_PRESENT)
+ {
+ fw_count++;
+ }
+
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
+ {
+ fw_count++;
+ }
+
+ p_res->result = NRF_DFU_RES_CODE_SUCCESS;
+
+ if (p_req->firmware.image_number == 0)
+ {
+ /* Bootloader is always present and it is always image zero. */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_BOOTLOADER;
+ p_res->firmware.version = s_dfu_settings.bootloader_version;
+ p_res->firmware.addr = BOOTLOADER_START_ADDR;
+ p_res->firmware.len = BOOTLOADER_SIZE;
+ }
+ else if ((p_req->firmware.image_number == 1) && SD_PRESENT)
+ {
+ /* If a SoftDevice is present, it will be firmware image one. */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_SOFTDEVICE;
+ p_res->firmware.version = SD_VERSION_GET(MBR_SIZE);
+ p_res->firmware.addr = MBR_SIZE;
+ p_res->firmware.len = SD_SIZE_GET(MBR_SIZE);
+ }
+ else if ((p_req->firmware.image_number < fw_count))
+ {
+ /* Either there is no SoftDevice and the firmware image requested is one,
+ * or there is a SoftDevice and the firmware image requested is two.
+ */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_APPLICATION;
+ p_res->firmware.version = s_dfu_settings.app_version;
+ p_res->firmware.addr = nrf_dfu_app_start_address();
+ p_res->firmware.len = s_dfu_settings.bank_0.image_size;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No such firmware image");
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_UNKNOWN;
+ p_res->firmware.version = 0x00;
+ p_res->firmware.addr = 0x00;
+ p_res->firmware.len = 0x00;
+ }
+ }
+ else
+ {
+ NRF_LOG_DEBUG("NRF_DFU_OP_FIRMWARE_VERSION disabled.");
+ p_res->result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_UNKNOWN;
+ }
+}
+
+
+static void on_ping_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_PING");
+ p_res->ping.id = p_req->ping.id;
+}
+
+
+static void on_mtu_get_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_MTU_GET");
+ p_res->mtu.size = p_req->mtu.size;
+}
+
+
+static void on_prn_set_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ UNUSED_PARAMETER(p_res);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_RECEIPT_NOTIF_SET");
+}
+
+
+static void on_abort_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ UNUSED_PARAMETER(p_res);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_ABORT");
+
+ m_observer(NRF_DFU_EVT_DFU_ABORTED);
+}
+
+
+/* Set offset and CRC fields in the response for a 'command' message. */
+static void cmd_response_offset_and_crc_set(nrf_dfu_response_t * const p_res)
+{
+ ASSERT(p_res);
+
+ /* Copy the CRC and offset of the init packet. */
+ p_res->crc.offset = s_dfu_settings.progress.command_offset;
+ p_res->crc.crc = s_dfu_settings.progress.command_crc;
+}
+
+
+static void on_cmd_obj_select_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (command)");
+
+ p_res->select.max_size = INIT_COMMAND_MAX_SIZE;
+ cmd_response_offset_and_crc_set(p_res);
+}
+
+
+static void on_cmd_obj_create_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_CREATE (command)");
+
+ m_observer(NRF_DFU_EVT_DFU_STARTED);
+
+ nrf_dfu_result_t ret_val = nrf_dfu_validation_init_cmd_create(p_req->create.object_size);
+ p_res->result = ext_err_code_handle(ret_val);
+}
+
+
+static void on_cmd_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_req->write.p_data);
+ ASSERT(p_req->write.len);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (command)");
+
+ nrf_dfu_result_t ret_val;
+
+ ret_val = nrf_dfu_validation_init_cmd_append(p_req->write.p_data, p_req->write.len);
+ p_res->result = ext_err_code_handle(ret_val);
+
+ /* Update response. This is only used when the PRN is triggered and the 'write' message
+ * is answered with a CRC message and these field are copied into the response. */
+ cmd_response_offset_and_crc_set(p_res);
+
+ /* If a callback to free the request payload buffer was provided, invoke it now. */
+ if (p_req->callback.write)
+ {
+ p_req->callback.write((void*)p_req->write.p_data);
+ }
+}
+
+
+static void on_cmd_obj_execute_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (command)");
+
+ nrf_dfu_result_t ret_val;
+ ret_val = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
+ p_res->result = ext_err_code_handle(ret_val);
+
+ if (p_res->result == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ if (nrf_dfu_settings_write(NULL) == NRF_SUCCESS)
+ {
+ /* Setting DFU to initialized */
+ NRF_LOG_DEBUG("Writing valid init command to flash.");
+ }
+ else
+ {
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+ }
+}
+
+
+static void on_cmd_obj_crc_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (command)");
+
+ cmd_response_offset_and_crc_set(p_res);
+}
+
+
+/** @brief Function handling command requests from the transport layer.
+ *
+ * @param p_req[in] Pointer to the structure holding the DFU request.
+ * @param p_res[out] Pointer to the structure holding the DFU response.
+ *
+ * @retval NRF_SUCCESS If the command request was executed successfully.
+ * Any other error code indicates that the data request
+ * could not be handled.
+ */
+static void nrf_dfu_command_req(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ on_cmd_obj_create_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ on_cmd_obj_crc_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ on_cmd_obj_write_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ {
+ on_cmd_obj_execute_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ on_cmd_obj_select_request(p_req, p_res);
+ } break;
+
+ default:
+ {
+ ASSERT(false);
+ } break;
+ }
+}
+
+
+static void on_data_obj_select_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (data)");
+
+ p_res->select.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->select.offset = s_dfu_settings.progress.firmware_image_offset;
+
+ p_res->select.max_size = DATA_OBJECT_MAX_SIZE;
+
+ NRF_LOG_DEBUG("crc = 0x%x, offset = 0x%x, max_size = 0x%x",
+ p_res->select.crc,
+ p_res->select.offset,
+ p_res->select.max_size);
+}
+
+
+static void on_data_obj_create_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_CREATE (data)");
+
+ if (!nrf_dfu_validation_init_cmd_present())
+ {
+ /* Can't accept data because DFU isn't initialized by init command. */
+ NRF_LOG_ERROR("Cannot create data object without valid init command");
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ if (p_req->create.object_size == 0)
+ {
+ NRF_LOG_ERROR("Object size cannot be 0.")
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ if ( ((p_req->create.object_size & (CODE_PAGE_SIZE - 1)) != 0)
+ && (s_dfu_settings.progress.firmware_image_offset_last + p_req->create.object_size != m_firmware_size_req))
+ {
+ NRF_LOG_ERROR("Object size must be page aligned");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ if (p_req->create.object_size > DATA_OBJECT_MAX_SIZE)
+ {
+ /* It is impossible to handle the command because the size is too large */
+ NRF_LOG_ERROR("Invalid size for object (too large)");
+ p_res->result = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ return;
+ }
+
+ if ((s_dfu_settings.progress.firmware_image_offset_last + p_req->create.object_size) >
+ m_firmware_size_req)
+ {
+ NRF_LOG_ERROR("Creating the object with size 0x%08x would overflow firmware size. "
+ "Offset is 0x%08x and firmware size is 0x%08x.",
+ p_req->create.object_size,
+ s_dfu_settings.progress.firmware_image_offset_last,
+ m_firmware_size_req);
+
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ s_dfu_settings.progress.data_object_size = p_req->create.object_size;
+ s_dfu_settings.progress.firmware_image_crc = s_dfu_settings.progress.firmware_image_crc_last;
+ s_dfu_settings.progress.firmware_image_offset = s_dfu_settings.progress.firmware_image_offset_last;
+ s_dfu_settings.write_offset = s_dfu_settings.progress.firmware_image_offset_last;
+
+ /* Erase the page we're at. */
+ if (nrf_dfu_flash_erase((m_firmware_start_addr + s_dfu_settings.progress.firmware_image_offset),
+ CEIL_DIV(p_req->create.object_size, CODE_PAGE_SIZE), NULL) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Erase operation failed");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ return;
+ }
+
+ NRF_LOG_DEBUG("Creating object with size: %d. Offset: 0x%08x, CRC: 0x%08x",
+ s_dfu_settings.progress.data_object_size,
+ s_dfu_settings.progress.firmware_image_offset,
+ s_dfu_settings.progress.firmware_image_crc);
+}
+
+
+static void on_data_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (data)");
+
+ if (!nrf_dfu_validation_init_cmd_present())
+ {
+ /* Can't accept data because DFU isn't initialized by init command. */
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ uint32_t const data_object_offset = s_dfu_settings.progress.firmware_image_offset -
+ s_dfu_settings.progress.firmware_image_offset_last;
+
+ if ((p_req->write.len + data_object_offset) > s_dfu_settings.progress.data_object_size)
+ {
+ /* Can't accept data because too much data has been received. */
+ NRF_LOG_ERROR("Write request too long");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ uint32_t const write_addr = m_firmware_start_addr + s_dfu_settings.write_offset;
+
+ ASSERT(p_req->callback.write);
+
+ ret_code_t ret =
+ nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write);
+
+ if (ret != NRF_SUCCESS)
+ {
+ /* When nrf_dfu_flash_store() fails because there is no space in the queue,
+ * stop processing the request so that the peer can detect a CRC error
+ * and retransmit this object. Remember to manually free the buffer !
+ */
+ p_req->callback.write((void*)p_req->write.p_data);
+ return;
+ }
+
+ /* Update the CRC of the firmware image. */
+ s_dfu_settings.write_offset += p_req->write.len;
+ s_dfu_settings.progress.firmware_image_offset += p_req->write.len;
+ s_dfu_settings.progress.firmware_image_crc =
+ crc32_compute(p_req->write.p_data, p_req->write.len, &s_dfu_settings.progress.firmware_image_crc);
+
+ /* This is only used when the PRN is triggered and the 'write' message
+ * is answered with a CRC message and these field are copied into the response.
+ */
+ p_res->write.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->write.offset = s_dfu_settings.progress.firmware_image_offset;
+}
+
+
+static void on_data_obj_crc_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (data)");
+ NRF_LOG_DEBUG("Offset:%d, CRC:0x%08x",
+ s_dfu_settings.progress.firmware_image_offset,
+ s_dfu_settings.progress.firmware_image_crc);
+
+ p_res->crc.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->crc.offset = s_dfu_settings.progress.firmware_image_offset;
+}
+
+
+static void on_data_obj_execute_request_sched(void * p_evt, uint16_t event_length)
+{
+ UNUSED_PARAMETER(event_length);
+
+ nrf_dfu_request_t * p_req = (nrf_dfu_request_t *)(p_evt);
+
+ /* Wait for all buffers to be written in flash. */
+ if (nrf_fstorage_is_busy(NULL))
+ {
+ ret_code_t ret = app_sched_event_put(p_req,
+ sizeof(nrf_dfu_request_t),
+ on_data_obj_execute_request_sched);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to schedule object execute: 0x%x.", ret);
+ }
+ return;
+ }
+
+ nrf_dfu_response_t res =
+ {
+ .request = NRF_DFU_OP_OBJECT_EXECUTE,
+ };
+
+ nrf_dfu_flash_callback_t dfu_settings_callback;
+
+ /* Whole firmware image was received, validate it. */
+ if (s_dfu_settings.progress.firmware_image_offset == m_firmware_size_req)
+ {
+ NRF_LOG_DEBUG("Postvalidation of firmware image.");
+
+ res.result = nrf_dfu_validation_post_data_execute(m_firmware_start_addr, m_firmware_size_req);
+ res.result = ext_err_code_handle(res.result);
+
+ /* Callback to on_dfu_complete() after updating the settings. */
+ dfu_settings_callback = (nrf_dfu_flash_callback_t)(on_dfu_complete);
+ }
+ else
+ {
+ res.result = NRF_DFU_RES_CODE_SUCCESS;
+ /* No callback required. */
+ dfu_settings_callback = NULL;
+ }
+
+ /* Provide response to transport */
+ p_req->callback.response(&res, p_req->p_context);
+
+ /* Store settings to flash if the whole image was received or if configured
+ * to save progress information in flash.
+ */
+ if ((dfu_settings_callback != NULL) || NRF_DFU_SAVE_PROGRESS_IN_FLASH)
+ {
+ ret_code_t ret = nrf_dfu_settings_write(dfu_settings_callback);
+ UNUSED_RETURN_VALUE(ret);
+ }
+
+ NRF_LOG_DEBUG("Request handling complete. Result: 0x%x", res.result);
+}
+
+
+static bool on_data_obj_execute_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (data)");
+
+ uint32_t const data_object_size = s_dfu_settings.progress.firmware_image_offset -
+ s_dfu_settings.progress.firmware_image_offset_last;
+
+ if (s_dfu_settings.progress.data_object_size != data_object_size)
+ {
+ /* The size of the written object was not as expected. */
+ NRF_LOG_ERROR("Invalid data. expected: %d, got: %d",
+ s_dfu_settings.progress.data_object_size,
+ data_object_size);
+
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return true;
+ }
+
+ /* Update the offset and crc values for the last object written. */
+ s_dfu_settings.progress.data_object_size = 0;
+ s_dfu_settings.progress.firmware_image_crc_last = s_dfu_settings.progress.firmware_image_crc;
+ s_dfu_settings.progress.firmware_image_offset_last = s_dfu_settings.progress.firmware_image_offset;
+
+ on_data_obj_execute_request_sched(p_req, 0);
+
+ m_observer(NRF_DFU_EVT_OBJECT_RECEIVED);
+
+ return false;
+}
+
+
+static bool nrf_dfu_data_req(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ bool response_ready = true;
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ on_data_obj_create_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ on_data_obj_write_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ on_data_obj_crc_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ {
+ response_ready = on_data_obj_execute_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ on_data_obj_select_request(p_req, p_res);
+ } break;
+
+ default:
+ {
+ ASSERT(false);
+ } break;
+ }
+
+ return response_ready;
+}
+
+
+/**@brief Function for handling requests to manipulate data or command objects.
+ *
+ * @param[in] p_req Request.
+ * @param[out] p_res Response.
+ *
+ * @return Whether response is ready to be sent.
+ */
+static bool nrf_dfu_obj_op(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ /* Keep track of the current object type since write and execute requests don't contain it. */
+ static nrf_dfu_obj_type_t current_object = NRF_DFU_OBJ_TYPE_COMMAND;
+
+ if ( (p_req->request == NRF_DFU_OP_OBJECT_SELECT)
+ || (p_req->request == NRF_DFU_OP_OBJECT_CREATE))
+ {
+ STATIC_ASSERT(offsetof(nrf_dfu_request_select_t, object_type) ==
+ offsetof(nrf_dfu_request_create_t, object_type),
+ "Wrong object_type offset!");
+
+ current_object = (nrf_dfu_obj_type_t)(p_req->select.object_type);
+ }
+
+ bool response_ready = true;
+
+ switch (current_object)
+ {
+ case NRF_DFU_OBJ_TYPE_COMMAND:
+ nrf_dfu_command_req(p_req, p_res);
+ break;
+
+ case NRF_DFU_OBJ_TYPE_DATA:
+ response_ready = nrf_dfu_data_req(p_req, p_res);
+ break;
+
+ default:
+ /* The select request had an invalid object type. */
+ NRF_LOG_ERROR("Invalid object type in request.");
+ current_object = NRF_DFU_OBJ_TYPE_INVALID;
+ p_res->result = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ break;
+ }
+
+ return response_ready;
+}
+
+
+static void nrf_dfu_req_handler_req_process(nrf_dfu_request_t * p_req)
+{
+ ASSERT(p_req->callback.response);
+
+ bool response_ready = true;
+
+ /* The request handlers assume these values to be set. */
+ nrf_dfu_response_t response =
+ {
+ .request = p_req->request,
+ .result = NRF_DFU_RES_CODE_SUCCESS,
+ };
+
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_PROTOCOL_VERSION:
+ {
+ on_protocol_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_HARDWARE_VERSION:
+ {
+ on_hw_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ on_fw_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_PING:
+ {
+ on_ping_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ on_prn_set_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_MTU_GET:
+ {
+ on_mtu_get_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_ABORT:
+ {
+ on_abort_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ /* Restart the inactivity timer on CREATE messages. */
+ /* Fallthrough. */
+ case NRF_DFU_OP_OBJECT_SELECT:
+ case NRF_DFU_OP_OBJECT_WRITE:
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ case NRF_DFU_OP_CRC_GET:
+ {
+ response_ready = nrf_dfu_obj_op(p_req, &response);
+ } break;
+
+ default:
+ NRF_LOG_INFO("Invalid opcode received: 0x%x.", p_req->request);
+ response.result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ if (response_ready)
+ {
+ NRF_LOG_DEBUG("Request handling complete. Result: 0x%x", response.result);
+
+ p_req->callback.response(&response, p_req->p_context);
+
+ if (response.result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ m_observer(NRF_DFU_EVT_DFU_FAILED);
+ }
+ }
+}
+
+
+static void nrf_dfu_req_handler_req(void * p_evt, uint16_t event_length)
+{
+ nrf_dfu_request_t * p_req = (nrf_dfu_request_t *)(p_evt);
+ nrf_dfu_req_handler_req_process(p_req);
+}
+
+
+ret_code_t nrf_dfu_req_handler_on_req(nrf_dfu_request_t * p_req)
+{
+ ret_code_t ret;
+
+ if (p_req->callback.response == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ ret = app_sched_event_put(p_req, sizeof(nrf_dfu_request_t), nrf_dfu_req_handler_req);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Scheduler ran out of space!");
+ }
+
+ return ret;
+}
+
+
+ret_code_t nrf_dfu_req_handler_init(nrf_dfu_observer_t observer)
+{
+ ret_code_t ret_val;
+ nrf_dfu_result_t result;
+
+ if (observer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ ret_val = nrf_dfu_flash_init(true);
+#else
+ ret_val = nrf_dfu_flash_init(false);
+#endif
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ nrf_dfu_validation_init();
+ if (nrf_dfu_validation_init_cmd_present())
+ {
+ /* Execute a previously received init packed. Subsequent executes will have no effect. */
+ result = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
+ if (result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ /* Init packet in flash is not valid! */
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ m_observer = observer;
+
+ /* Initialize extended error handling with "No error" as the most recent error. */
+ result = ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+ UNUSED_RETURN_VALUE(result);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h
new file mode 100644
index 0000000..c9d10d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h
@@ -0,0 +1,345 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_req_handler Request handling
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_REQ_HANDLER_H__
+#define NRF_DFU_REQ_HANDLER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util_platform.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ANON_UNIONS_ENABLE;
+
+/**
+ * @brief DFU object types.
+ */
+typedef enum
+{
+ NRF_DFU_OBJ_TYPE_INVALID, //!< Invalid object type.
+ NRF_DFU_OBJ_TYPE_COMMAND, //!< Command object.
+ NRF_DFU_OBJ_TYPE_DATA, //!< Data object.
+} nrf_dfu_obj_type_t;
+
+/**
+ * @brief DFU protocol operation.
+ */
+typedef enum
+{
+ NRF_DFU_OP_PROTOCOL_VERSION = 0x00, //!< Retrieve protocol version.
+ NRF_DFU_OP_OBJECT_CREATE = 0x01, //!< Create selected object.
+ NRF_DFU_OP_RECEIPT_NOTIF_SET = 0x02, //!< Set receipt notification.
+ NRF_DFU_OP_CRC_GET = 0x03, //!< Request CRC of selected object.
+ NRF_DFU_OP_OBJECT_EXECUTE = 0x04, //!< Execute selected object.
+ NRF_DFU_OP_OBJECT_SELECT = 0x06, //!< Select object.
+ NRF_DFU_OP_MTU_GET = 0x07, //!< Retrieve MTU size.
+ NRF_DFU_OP_OBJECT_WRITE = 0x08, //!< Write selected object.
+ NRF_DFU_OP_PING = 0x09, //!< Ping.
+ NRF_DFU_OP_HARDWARE_VERSION = 0x0A, //!< Retrieve hardware version.
+ NRF_DFU_OP_FIRMWARE_VERSION = 0x0B, //!< Retrieve firmware version.
+ NRF_DFU_OP_ABORT = 0x0C, //!< Abort the DFU procedure.
+ NRF_DFU_OP_RESPONSE = 0x60, //!< Response.
+ NRF_DFU_OP_INVALID = 0xFF,
+} nrf_dfu_op_t;
+
+/**
+ * @brief DFU operation result code.
+ */
+typedef enum
+{
+ NRF_DFU_RES_CODE_INVALID = 0x00, //!< Invalid opcode.
+ NRF_DFU_RES_CODE_SUCCESS = 0x01, //!< Operation successful.
+ NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED = 0x02, //!< Opcode not supported.
+ NRF_DFU_RES_CODE_INVALID_PARAMETER = 0x03, //!< Missing or invalid parameter value.
+ NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES = 0x04, //!< Not enough memory for the data object.
+ NRF_DFU_RES_CODE_INVALID_OBJECT = 0x05, //!< Data object does not match the firmware and hardware requirements, the signature is wrong, or parsing the command failed.
+ NRF_DFU_RES_CODE_UNSUPPORTED_TYPE = 0x07, //!< Not a valid object type for a Create request.
+ NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED = 0x08, //!< The state of the DFU process does not allow this operation.
+ NRF_DFU_RES_CODE_OPERATION_FAILED = 0x0A, //!< Operation failed.
+ NRF_DFU_RES_CODE_EXT_ERROR = 0x0B, //!< Extended error. The next byte of the response contains the error code of the extended error (see @ref nrf_dfu_ext_error_code_t.
+} nrf_dfu_result_t;
+
+typedef enum
+{
+ NRF_DFU_FIRMWARE_TYPE_SOFTDEVICE = 0x00,
+ NRF_DFU_FIRMWARE_TYPE_APPLICATION = 0x01,
+ NRF_DFU_FIRMWARE_TYPE_BOOTLOADER = 0x02,
+ NRF_DFU_FIRMWARE_TYPE_UNKNOWN = 0xFF,
+} nrf_dfu_firmware_type_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PROTOCOL_VERSION response details.
+ */
+typedef struct
+{
+ uint8_t version; //!< Protocol version.
+} nrf_dfu_response_protocol_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_HARDWARE_VERSION response details.
+ */
+typedef struct
+{
+ uint32_t part; //!< Hardware part, from FICR register.
+ uint32_t variant; //!< Hardware variant, from FICR register.
+ struct
+ {
+ uint32_t rom_size; //!< ROM size, in bytes.
+ uint32_t ram_size; //!< RAM size, in bytes.
+ uint32_t rom_page_size; //!< ROM flash page size, in bytes.
+ } memory;
+} nrf_dfu_response_hardware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_FIRMWARE_VERSION response details.
+ */
+typedef struct
+{
+ nrf_dfu_firmware_type_t type; //!< Firmware type.
+ uint32_t version; //!< Firmware version.
+ uint32_t addr; //!< Firmware address in flash.
+ uint32_t len; //!< Firmware length in bytes.
+} nrf_dfu_response_firmware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_SELECT response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset.
+ uint32_t crc; //!< Current CRC.
+ uint32_t max_size; //!< Maximum size of selected object.
+} nrf_dfu_response_select_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_CREATE response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset
+ uint32_t crc; //!< Current CRC.
+} nrf_dfu_response_create_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_WRITE response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Used only when packet receipt notification is used.
+ uint32_t crc; //!< Used only when packet receipt notification is used.
+} nrf_dfu_response_write_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_CRC_GET response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset.
+ uint32_t crc; //!< Current CRC.
+} nrf_dfu_response_crc_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PING response details.
+ */
+typedef struct
+{
+ uint8_t id; //!< The received ID which is echoed back.
+} nrf_dfu_response_ping_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_MTU_GET response details.
+ */
+typedef struct
+{
+ uint16_t size; //!< The MTU size as specified by the local transport.
+} nrf_dfu_response_mtu_t;
+
+/**
+ * @brief DFU response message.
+ */
+typedef struct
+{
+ nrf_dfu_op_t request; //!< Requested operation.
+ nrf_dfu_result_t result; //!< Result of the operation.
+ union
+ {
+ nrf_dfu_response_protocol_t protocol; //!< Protocol version response.
+ nrf_dfu_response_hardware_t hardware; //!< Hardware version response.
+ nrf_dfu_response_firmware_t firmware; //!< Firmware version response.
+ nrf_dfu_response_select_t select; //!< Select object response..
+ nrf_dfu_response_create_t create; //!< Create object response..
+ nrf_dfu_response_write_t write; //!< Write object response.
+ nrf_dfu_response_crc_t crc; //!< CRC response.
+ nrf_dfu_response_ping_t ping; //!< Ping response.
+ nrf_dfu_response_mtu_t mtu; //!< MTU response.
+ };
+} nrf_dfu_response_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_FIRMWARE_VERSION request details.
+ */
+typedef struct
+{
+ uint8_t image_number; //!< Index of the firmware.
+} nrf_dfu_request_firmware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_SELECT request details.
+ */
+typedef struct
+{
+ uint32_t object_type; //!< Object type. See @ref nrf_dfu_obj_type_t.
+} nrf_dfu_request_select_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_CREATE request details.
+ */
+typedef struct
+{
+ uint32_t object_type; //!< Object type. See @ref nrf_dfu_obj_type_t.
+ uint32_t object_size; //!< Object size in bytes.
+} nrf_dfu_request_create_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_WRITE request details.
+ */
+typedef struct
+{
+ uint8_t const * p_data; //!< Data.
+ uint16_t len; //!< Length of data in @ref nrf_dfu_request_write_t::p_data.
+} nrf_dfu_request_write_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PING request details.
+ */
+typedef struct
+{
+ uint8_t id; //!< Ping ID that will be returned in response.
+} nrf_dfu_request_ping_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_MTU_GET request details.
+ */
+typedef struct
+{
+ uint16_t size; //!< Transport MTU size in bytes.
+} nrf_dfu_request_mtu_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_RECEIPT_NOTIF_SET request details.
+ */
+typedef struct
+{
+ uint32_t target; //!< Target PRN.
+} nrf_dfu_request_prn_t;
+
+
+typedef void (*nrf_dfu_response_callback_t)(nrf_dfu_response_t * p_res, void * p_context);
+
+/**
+ *@brief DFU request.
+ */
+typedef struct
+{
+ nrf_dfu_op_t request; //!< Requested operation.
+ void * p_context;
+ struct
+ {
+ nrf_dfu_response_callback_t response; //!< Callback to call to send the response.
+ nrf_dfu_flash_callback_t write;
+ } callback;
+ union
+ {
+ nrf_dfu_request_firmware_t firmware; //!< Firmware version request.
+ nrf_dfu_request_select_t select; //!< Select object request.
+ nrf_dfu_request_create_t create; //!< Create object request.
+ nrf_dfu_request_write_t write; //!< Write object request.
+ nrf_dfu_request_ping_t ping; //!< Ping.
+ nrf_dfu_request_mtu_t mtu; //!< MTU size request.
+ nrf_dfu_request_prn_t prn; //!< Set receipt notification request.
+ };
+} nrf_dfu_request_t;
+
+
+/**@brief Function for initializing the request handling module.
+ *
+ * @param observer Function for receiving notifications.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INTERNAL If the init packet in flash is not valid.
+ * @retval NRF_ERROR_INVALID_PARAM If observer is not provided.
+ */
+ret_code_t nrf_dfu_req_handler_init(nrf_dfu_observer_t observer);
+
+
+/**@brief Function for scheduling processing of a DFU request.
+ *
+ * Requests are processed asynchronously by the scheduler.
+ *
+ * @param[in] p_req Request to be handled. The response callback must be non-null.
+ *
+ * @retval NRF_SUCCESS If the command request was executed successfully.
+ * @retval NRF_ERROR_NO_MEM If the scheduler ran out of memory.
+ * @retval NRF_ERROR_INVALID_PARAM If the response callback is NULL.
+ */
+ret_code_t nrf_dfu_req_handler_on_req(nrf_dfu_request_t * p_req);
+
+
+ANON_UNIONS_DISABLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_REQ_HANDLER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c
new file mode 100644
index 0000000..13e89b4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_settings.h"
+#include <stddef.h>
+#include <string.h>
+#include "app_error.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_soc.h"
+#include "crc32.h"
+#include "nrf_nvmc.h"
+
+#define DFU_SETTINGS_INIT_COMMAND_OFFSET offsetof(nrf_dfu_settings_t, init_command) //<! Offset in the settings struct where the InitCommand is located.
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_settings
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/**@brief This variable reserves a page in flash for bootloader settings
+ * to ensure the linker doesn't place any code or variables at this location.
+ */
+#if defined (__CC_ARM )
+
+ uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
+ __attribute__((used));
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ __attribute__((section(".bootloader_settings_page")))
+ __attribute__((used));
+
+#elif defined ( __ICCARM__ )
+
+ __no_init __root uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ @ BOOTLOADER_SETTINGS_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_dfu_settings placement.
+
+#endif // Compiler specific
+
+#ifndef BL_SETTINGS_ACCESS_ONLY
+#if defined(NRF52_SERIES)
+
+/**@brief This variable reserves a page in flash for MBR parameters
+ * to ensure the linker doesn't place any code or variables at this location.
+ */
+#if defined ( __CC_ARM )
+
+ uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ __attribute__((at(NRF_MBR_PARAMS_PAGE_ADDRESS)))
+ __attribute__((used));
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ __attribute__ ((section(".mbr_params_page")));
+
+#elif defined ( __ICCARM__ )
+
+ __no_init uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ @ NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_mbr_params_page placement.
+
+#endif // Compiler specific
+
+
+/**@brief This variable has the linker write the MBR parameters page address to the
+ * UICR register. This value will be written in the HEX file and thus to the
+ * UICR when the bootloader is flashed into the chip.
+ */
+#if defined ( __CC_ARM )
+
+ uint32_t const m_uicr_mbr_params_page_address
+ __attribute__((at(NRF_UICR_MBR_PARAMS_PAGE_ADDRESS))) = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint32_t const m_uicr_mbr_params_page_address
+ __attribute__ ((section(".uicr_mbr_params_page")))
+ __attribute__ ((used)) = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#elif defined ( __ICCARM__ )
+
+ __root uint32_t const m_uicr_mbr_params_page_address
+ @ NRF_UICR_MBR_PARAMS_PAGE_ADDRESS = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_mbr_params_page placement.
+
+#endif // Compiler specific
+#endif // #if defined( NRF52_SERIES )
+#endif // #ifndef BL_SETTINGS_ACCESS_ONLY
+
+
+nrf_dfu_settings_t s_dfu_settings;
+
+
+static uint32_t nrf_dfu_settings_crc_get(void)
+{
+ // The crc is calculated from the s_dfu_settings struct, except the crc itself and the init command
+ return crc32_compute((uint8_t*)&s_dfu_settings + 4, DFU_SETTINGS_INIT_COMMAND_OFFSET - 4, NULL);
+}
+
+
+ret_code_t nrf_dfu_settings_init(bool sd_irq_initialized)
+{
+ NRF_LOG_DEBUG("Calling nrf_dfu_settings_init()...");
+
+ ret_code_t rc = nrf_dfu_flash_init(sd_irq_initialized);
+ if (rc != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("nrf_dfu_flash_init() failed with error: %x", rc);
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Copy the DFU settings out of flash and into a buffer in RAM.
+ memcpy((void*)&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t));
+
+ if (s_dfu_settings.crc != 0xFFFFFFFF)
+ {
+ // CRC is set. Content must be valid
+ uint32_t crc = nrf_dfu_settings_crc_get();
+ if (crc == s_dfu_settings.crc)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+
+ // Reached if the page is erased or CRC is wrong.
+ NRF_LOG_DEBUG("Resetting bootloader settings.");
+
+ memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t));
+ s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
+
+ rc = nrf_dfu_settings_write(NULL);
+ if (rc != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("nrf_dfu_flash_write() failed with error: %x", rc);
+ return NRF_ERROR_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_dfu_settings_write(nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t err_code;
+
+ if (memcmp(&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t)) == 0)
+ {
+ NRF_LOG_DEBUG("New settings are identical to old, write not needed. Skipping.");
+ if (callback != NULL)
+ {
+ callback(NULL);
+ }
+ return NRF_SUCCESS;
+ }
+
+ NRF_LOG_DEBUG("Writing settings...");
+ NRF_LOG_DEBUG("Erasing old settings at: 0x%08x", (uint32_t)m_dfu_settings_buffer);
+
+ // Not setting the callback function because ERASE is required before STORE
+ // Only report completion on successful STORE.
+ err_code = nrf_dfu_flash_erase((uint32_t)m_dfu_settings_buffer, 1, NULL);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not erase the settings page!");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ s_dfu_settings.crc = nrf_dfu_settings_crc_get();
+
+ static nrf_dfu_settings_t temp_dfu_settings;
+ memcpy(&temp_dfu_settings, &s_dfu_settings, sizeof(nrf_dfu_settings_t));
+
+ err_code = nrf_dfu_flash_store((uint32_t)m_dfu_settings_buffer,
+ &temp_dfu_settings,
+ sizeof(nrf_dfu_settings_t),
+ callback);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not write the DFU settings page!");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+__WEAK ret_code_t nrf_dfu_settings_additional_erase(void)
+{
+ NRF_LOG_WARNING("No additional data erased");
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h
new file mode 100644
index 0000000..9e9dedb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu_settings DFU settings
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_SETTINGS_H__
+#define NRF_DFU_SETTINGS_H__
+
+#include <stdint.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_flash.h"
+#include "sdk_config.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Global settings.
+ *
+ * @note Using this variable is not thread-safe.
+ *
+ */
+extern nrf_dfu_settings_t s_dfu_settings;
+
+
+/**@brief Function for writing DFU settings to flash.
+ *
+ * @param[in] callback Pointer to a function that is called after completing the write operation.
+ *
+ * @retval NRF_SUCCESS If the write process was successfully initiated.
+ * @retval NRF_ERROR_INTERNAL If a flash error occurred.
+ */
+ret_code_t nrf_dfu_settings_write(nrf_dfu_flash_callback_t callback);
+
+
+/**@brief Function for initializing the DFU settings module.
+ *
+ * @retval NRF_SUCCESS If the initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If a flash error occurred.
+ */
+ret_code_t nrf_dfu_settings_init(bool sd_irq_initialized);
+
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+/** @brief Function for storing peer data received through an SVCI call in DFU settings.
+ *
+ * @note The content of the type can be verified by a CRC value stored inside the struct
+ * If the CRC value is 0xFFFFFFFF, it means that no data is set.
+ *
+ * @note The storage operation is an asynchronous progress. Success will be notified
+ * through system events raised by the SoftDevice.
+ *
+ * @param[in] p_data Peer data to be stored in flash.
+ *
+ * @retval NRF_SUCCESS Asynchronous operation was successfully started.
+ * @retval NRF_ERROR_NULL p_data was NULL.
+ * @retval Any other error code reported by SoftDevice API calls.
+ */
+ret_code_t nrf_dfu_settings_peer_data_write(nrf_dfu_peer_data_t * p_data);
+
+
+/** @brief Function for copying peer data from DFU settings to RAM.
+ *
+ * @param[in,out] p_data Structure to copy peer data to.
+ *
+ * @retval NRF_SUCCESS Peer data was successfully copied.
+ * @retval NRF_ERROR_NULL p_data was NULL.
+ */
+ret_code_t nrf_dfu_settings_peer_data_copy(nrf_dfu_peer_data_t * p_data);
+
+
+/** @brief Function for validating peer data in DFU settings.
+ *
+ * @retval True if peer data is validated by CRC, false if not.
+ */
+bool nrf_dfu_settings_peer_data_is_valid(void);
+
+
+/** @brief Function for storing an advertisement name received through an SVCI call in DFU settings.
+ *
+ * @note The content of the type is verifyable by a CRC-value stored inside the struct.
+ *
+ * @note The storage operation is an asynchronous progress. Success will be notified
+ * through system events raised by the SoftDevice.
+ *
+ * @param[in] p_adv_name Structure holding information about the new advertisement name.
+ *
+ * @retval NRF_SUCCESS Asynchronous operation was successfully started.
+ * @retval NRF_ERROR_NULL p_adv_name was NULL.
+ * @retval Any other error code reported by SoftDevice API calls.
+ */
+ret_code_t nrf_dfu_settings_adv_name_write(nrf_dfu_adv_name_t * p_adv_name);
+
+
+/** @brief Function for copying the advertisement name from DFU settings to RAM.
+ *
+ * @param[in,out] p_adv_name Structure to copy the new advertisement name to.
+ *
+ * @retval NRF_SUCCESS Advertisement name was successfully copied.
+ * @retval NRF_ERROR_NULL p_adv_name was NULL.
+ */
+ret_code_t nrf_dfu_settings_adv_name_copy(nrf_dfu_adv_name_t * p_adv_name);
+
+
+/** @brief Function for validating advertisement data in DFU settings.
+ *
+ * @retval True if advertisement name is validated by CRC, false if not.
+ */
+bool nrf_dfu_settings_adv_name_is_valid(void);
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+/** @brief Function for erasing additional data in DFU settings.
+ *
+ * @note Erasing additional data in DFU settings is only possible
+ * if nrf_dfu_flash is initialized to not use SoftDevice calls.
+ *
+ * @retval NRF_SUCCESS Additional data was successfully erased.
+ * @retval Any other error code reported by nrf_dfu_flash
+ */
+ret_code_t nrf_dfu_settings_additional_erase(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_SETTINGS_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c
new file mode 100644
index 0000000..41deb9e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include "app_error.h"
+#include "sdk_macros.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_nvmc.h"
+#include "crc32.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_settings_svci
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define DFU_SETTINGS_PEER_DATA_OFFSET offsetof(nrf_dfu_settings_t, peer_data) //<! Offset in the settings struct where the additional peer data is located.
+#define DFU_SETTINGS_ADV_NAME_OFFSET offsetof(nrf_dfu_settings_t, adv_name) //<! Offset in the settings struct where the additional advertisement name is located.
+
+extern nrf_dfu_settings_t s_dfu_settings;
+extern uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE];
+
+#if defined(NRF_DFU_BLE_REQUIRES_BONDS) && (NRF_DFU_BLE_REQUIRES_BONDS == 1)
+
+ret_code_t nrf_dfu_settings_peer_data_write(nrf_dfu_peer_data_t * p_data)
+{
+ uint32_t ret_val;
+
+ uint32_t * p_peer_data_settings =
+ (uint32_t*) &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET];
+
+ uint32_t crc = (uint32_t)*p_peer_data_settings;
+
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if (crc != 0xFFFFFFFF)
+ {
+ // Already written to, must be cleared out
+ // Reset required.
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ p_data->crc = crc32_compute((uint8_t*)p_data + 4, sizeof(nrf_dfu_peer_data_t) - 4, NULL);
+
+ // Using SoftDevice call since this function cannot use static memory.
+ ret_val = sd_flash_write(p_peer_data_settings,
+ (uint32_t*)p_data,
+ sizeof(nrf_dfu_peer_data_t)/4);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_dfu_settings_peer_data_copy(nrf_dfu_peer_data_t * p_data)
+{
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ memcpy(p_data, &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET], sizeof(nrf_dfu_peer_data_t));
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_dfu_settings_peer_data_is_valid(void)
+{
+ nrf_dfu_peer_data_t * p_peer_data =
+ (nrf_dfu_peer_data_t*) &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET];
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ uint32_t crc = crc32_compute((uint8_t*)p_peer_data + 4, sizeof(nrf_dfu_peer_data_t) - 4, NULL);
+
+ return (p_peer_data->crc == crc);
+}
+
+#else // not NRF_DFU_BLE_REQUIRES_BONDS
+
+ret_code_t nrf_dfu_settings_adv_name_write(nrf_dfu_adv_name_t * p_adv_name)
+{
+ uint32_t ret_val;
+
+ uint32_t * p_adv_name_settings =
+ (uint32_t*) &m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET];
+
+ uint32_t crc = (uint32_t)*p_adv_name_settings;
+
+ VERIFY_PARAM_NOT_NULL(p_adv_name);
+
+ if (crc != 0xFFFFFFFF)
+ {
+ // Already written to, must be cleared out.
+ // Reset required
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ p_adv_name->crc = crc32_compute((uint8_t *)p_adv_name + 4, sizeof(nrf_dfu_adv_name_t) - 4, NULL);
+
+ // Using SoftDevice call since this function cannot use static memory.
+ ret_val = sd_flash_write(p_adv_name_settings,
+ (uint32_t*) p_adv_name,
+ sizeof(nrf_dfu_adv_name_t)/4);
+ return ret_val;
+}
+
+
+ret_code_t nrf_dfu_settings_adv_name_copy(nrf_dfu_adv_name_t * p_adv_name)
+{
+ VERIFY_PARAM_NOT_NULL(p_adv_name);
+ memcpy(p_adv_name, &m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET], sizeof(nrf_dfu_adv_name_t));
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_dfu_settings_adv_name_is_valid(void)
+{
+ nrf_dfu_adv_name_t * p_adv_name =
+ (nrf_dfu_adv_name_t*)&m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET];
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ uint32_t crc = crc32_compute((uint8_t*)p_adv_name + 4, sizeof(nrf_dfu_adv_name_t) - 4, NULL);
+
+ return (p_adv_name->crc == crc);
+}
+
+#endif
+
+
+//lint -save -e(14)
+ret_code_t nrf_dfu_settings_additional_erase(void)
+{
+ ret_code_t ret_code = NRF_SUCCESS;
+
+ // Check CRC for both types.
+ if ( (s_dfu_settings.peer_data.crc != 0xFFFFFFFF)
+ || (s_dfu_settings.adv_name.crc != 0xFFFFFFFF))
+ {
+ NRF_LOG_DEBUG("Erasing settings page additional data.");
+
+ // Erasing and resetting the settings page without the peer data/adv data
+ nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
+ nrf_nvmc_write_words(BOOTLOADER_SETTINGS_ADDRESS, (uint32_t const *)&s_dfu_settings, DFU_SETTINGS_PEER_DATA_OFFSET / 4);
+ }
+
+ return ret_code;
+}
+//lint -restore
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c
new file mode 100644
index 0000000..ceff394
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log.h"
+#include "nrf_sdm.h"
+#include "app_util.h"
+
+#define APP_START_ADDR CODE_START
+
+
+uint32_t nrf_dfu_svci_vector_table_set(void)
+{
+ uint32_t err_code;
+
+ if (NRF_UICR->NRFFW[0] != 0xFFFFFFFF)
+ {
+ NRF_LOG_INFO("Setting vector table to bootloader: 0x%08x", NRF_UICR->NRFFW[0]);
+ err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ NRF_LOG_ERROR("No bootloader was found");
+ return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t nrf_dfu_svci_vector_table_unset(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_INFO("Setting vector table to main app: 0x%08x", APP_START_ADDR);
+ err_code = sd_softdevice_vector_table_base_set(APP_START_ADDR);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c
new file mode 100644
index 0000000..ce75be7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include "nrf_svci_async_handler.h"
+#include "app_error.h"
+#include "nrf_nvmc.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nrf_log.h"
+#include "nrf_dfu_settings.h"
+#include "sdk_config.h"
+
+
+#if (NRF_DFU_TRANSPORT_BLE && NRF_DFU_BLE_REQUIRES_BONDS)
+
+
+NRF_SVCI_ASYNC_HANDLER_CREATE(NRF_DFU_SVCI_SET_PEER_DATA,
+ nrf_dfu_set_peer_data, nrf_dfu_peer_data_t, nrf_dfu_peer_data_state_t);
+
+
+static uint32_t nrf_dfu_set_peer_data_handler(nrf_dfu_set_peer_data_svci_async_t * p_async)
+{
+ VERIFY_PARAM_NOT_NULL(p_async);
+
+ p_async->async_func = nrf_dfu_set_peer_data_on_call;
+ p_async->sys_evt_handler = nrf_dfu_set_peer_data_on_sys_evt;
+ p_async->state = DFU_PEER_DATA_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t nrf_dfu_set_peer_data_on_call(nrf_dfu_peer_data_t * p_data,
+ nrf_dfu_peer_data_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_BUSY;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ switch (*p_state)
+ {
+ case DFU_PEER_DATA_STATE_INVALID:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_PEER_DATA_STATE_INITIALIZED:
+ ret_val = nrf_dfu_settings_peer_data_write(p_data);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_state = DFU_PEER_DATA_STATE_WRITE_REQUESTED;
+ }
+ break;
+
+ case DFU_PEER_DATA_STATE_WRITE_REQUESTED:
+ return NRF_ERROR_BUSY;
+
+ case DFU_PEER_DATA_STATE_WRITE_FINISHED:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_PEER_DATA_STATE_WRITE_FAILED:
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_dfu_set_peer_data_on_sys_evt(uint32_t sys_event, nrf_dfu_peer_data_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_STATE;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (*p_state == DFU_PEER_DATA_STATE_WRITE_REQUESTED)
+ {
+ switch (sys_event)
+ {
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ return NRF_ERROR_BUSY;
+
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ (*p_state) = DFU_PEER_DATA_STATE_WRITE_FINISHED;
+ break;
+
+ default:
+ // Event not intended for us
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+#elif (NRF_DFU_TRANSPORT_BLE && !NRF_DFU_BLE_REQUIRES_BONDS)
+
+
+NRF_SVCI_ASYNC_HANDLER_CREATE(NRF_DFU_SVCI_SET_ADV_NAME,
+ nrf_dfu_set_adv_name, nrf_dfu_adv_name_t, nrf_dfu_set_adv_name_state_t);
+
+
+static uint32_t nrf_dfu_set_adv_name_handler(nrf_dfu_set_adv_name_svci_async_t * p_async)
+{
+ VERIFY_PARAM_NOT_NULL(p_async);
+
+ p_async->async_func = nrf_dfu_set_adv_name_on_call;
+ p_async->sys_evt_handler = nrf_dfu_set_adv_name_on_sys_evt;
+ p_async->state = DFU_ADV_NAME_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t nrf_dfu_set_adv_name_on_call(nrf_dfu_adv_name_t * p_adv_name,
+ nrf_dfu_set_adv_name_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_BUSY;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ switch (*p_state)
+ {
+ case DFU_ADV_NAME_STATE_INVALID:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_ADV_NAME_STATE_INITIALIZED:
+ ret_val = nrf_dfu_settings_adv_name_write(p_adv_name);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_state = DFU_ADV_NAME_STATE_WRITE_REQUESTED;
+ }
+ break;
+
+ case DFU_ADV_NAME_STATE_WRITE_REQUESTED:
+ return NRF_ERROR_BUSY;
+
+ case DFU_ADV_NAME_STATE_WRITE_FINISHED:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_ADV_NAME_STATE_WRITE_FAILED:
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_dfu_set_adv_name_on_sys_evt(uint32_t sys_event, nrf_dfu_set_adv_name_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_STATE;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (*p_state == DFU_ADV_NAME_STATE_WRITE_REQUESTED)
+ {
+ switch (sys_event)
+ {
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ return NRF_ERROR_BUSY;
+
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ (*p_state) = DFU_ADV_NAME_STATE_WRITE_FINISHED;
+ break;
+
+ default:
+ // Event not intended for us
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+#endif // NRF_DFU_TRANSPORT_BLE && !NRF_DFU_BLE_REQUIRES_BONDS
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c
new file mode 100644
index 0000000..6075538
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_transport.h"
+#include "nrf_log.h"
+
+
+#define DFU_TRANS_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(dfu_trans, nrf_dfu_transport_t, (i))
+#define DFU_TRANS_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(dfu_trans, nrf_dfu_transport_t)
+
+NRF_SECTION_DEF(dfu_trans, const nrf_dfu_transport_t);
+
+
+uint32_t nrf_dfu_transports_init(nrf_dfu_observer_t observer)
+{
+ uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT;
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Initializing transports (found: %d)", num_transports);
+
+ for (uint32_t i = 0; i < num_transports; i++)
+ {
+ nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i);
+ ret_val = trans->init_func(observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Failed to initialize transport %d, error %d", i, ret_val);
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_transports_close(nrf_dfu_transport_t const * p_exception)
+{
+ uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT;
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Shutting down transports (found: %d)", num_transports);
+
+ for (uint32_t i = 0; i < num_transports; i++)
+ {
+ nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i);
+ ret_val = trans->close_func(p_exception);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Failed to shutdown transport %d, error %d", i, ret_val);
+ break;
+ }
+ }
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h
new file mode 100644
index 0000000..b8368f0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_transport DFU transport
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Generic Device Firmware Update (DFU) transport interface.
+ *
+ * @details The DFU transport module defines a generic interface that must
+ * be implemented for each transport layer.
+ */
+
+#ifndef NRF_DFU_TRANSPORT_H__
+#define NRF_DFU_TRANSPORT_H__
+
+#include <stdint.h>
+#include "nrf_section.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Forward declaration of nrf_dfu_transport_t */
+typedef struct nrf_dfu_transport_s nrf_dfu_transport_t;
+
+/** @brief Function type for initializing a DFU transport.
+ *
+ * @details This function initializes a DFU transport. The implementation
+ * of the function must initialize DFU mode and stay in service
+ * until either the device is reset or the DFU operation is finalized.
+ * When the DFU transport receives requests, it should call @ref nrf_dfu_req_handler_on_req for handling the requests.
+ *
+ * @param observer Function for receiving DFU transport notifications.
+ *
+ * @retval NRF_SUCCESS If initialization was successful for the transport. Any other return code indicates that the DFU transport could not be initialized.
+ */
+typedef uint32_t (*nrf_dfu_init_fn_t)(nrf_dfu_observer_t observer);
+
+
+/** @brief Function type for closing down a DFU transport.
+ *
+ * @details This function closes down a DFU transport in a gentle way.
+ *
+ * @param[in] p_exception If exception matches current transport closing should be omitted.
+ *
+ * @retval NRF_SUCCESS If closing was successful for the transport. Any other return code indicates that the DFU transport could not be closed closed down.
+ */
+typedef uint32_t (*nrf_dfu_close_fn_t)(nrf_dfu_transport_t const * p_exception);
+
+
+
+/** @brief DFU transport registration.
+ *
+ * @details Every DFU transport must provide a registration of the initialization function.
+ */
+struct nrf_dfu_transport_s
+{
+ nrf_dfu_init_fn_t init_func; /**< Registration of the init function to run to initialize a DFU transport. */
+ nrf_dfu_close_fn_t close_func; /**< Registration of the close function to close down a DFU transport. */
+};
+
+
+/** @brief Function for initializing all the registered DFU transports.
+ *
+ * @retval NRF_SUCCESS If all DFU transport were initialized successfully.
+ * Any other error code indicates that at least one DFU
+ * transport could not be initialized.
+ */
+uint32_t nrf_dfu_transports_init(nrf_dfu_observer_t observer);
+
+/** @brief Function for closing down all (with optional exception) the registered DFU transports.
+ *
+ * @param[in] p_exception Transport which should not be closed. NULL if all transports should be closed.
+ * @retval NRF_SUCCESS If all DFU transport were closed down successfully.
+ * Any other error code indicates that at least one DFU
+ * transport could not be closed down.
+ */
+uint32_t nrf_dfu_transports_close(nrf_dfu_transport_t const * p_exception);
+
+
+/** @brief Macro for registering a DFU transport by using section variables.
+ *
+ * @details This macro places a variable in a section named "dfu_trans", which
+ * is initialized by @ref nrf_dfu_transports_init.
+ */
+#define DFU_TRANSPORT_REGISTER(trans_var) NRF_SECTION_ITEM_REGISTER(dfu_trans, trans_var)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_TRANSPORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c
new file mode 100644
index 0000000..582d60c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_trigger_usb.h"
+#include "app_usbd_string_config.h"
+#include "app_usbd.h"
+#include "app_usbd_nrf_dfu_trigger.h"
+#include "nrf_drv_clock.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+#include "app_util.h"
+#include "app_usbd_serial_num.h"
+#define NRF_LOG_MODULE_NAME nrf_dfu_trigger_usb
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifndef BSP_SELF_PINRESET_PIN
+#error "This module is intended to be used with boards that have the GP pin shortened with the RESET pin."
+#endif
+
+/**
+ * @brief Enable power USB detection.
+ *
+ * Configure if the example supports USB port connection.
+ */
+#ifndef USBD_POWER_DETECTION
+#define USBD_POWER_DETECTION true
+#endif
+
+#define DFU_FLASH_PAGE_SIZE (NRF_FICR->CODEPAGESIZE)
+#define DFU_FLASH_PAGE_COUNT (NRF_FICR->CODESIZE)
+
+// Semantic versioning string.
+#define VERSION_STRING STRINGIFY(APP_VERSION_MAJOR) "." STRINGIFY(APP_VERSION_MINOR) "." STRINGIFY(APP_VERSION_PATCH) APP_VERSION_PRERELEASE APP_VERSION_METADATA
+
+static uint8_t m_version_string[] = APP_NAME " " VERSION_STRING; ///< Human-readable version string.
+static app_usbd_nrf_dfu_trigger_nordic_info_t m_dfu_info; ///< Struct with various information about the current firmware.
+
+static void dfu_trigger_evt_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_nrf_dfu_trigger_user_event_t event)
+{
+ UNUSED_PARAMETER(p_inst);
+
+ switch (event)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH:
+ NRF_LOG_INFO("DFU Detach request received. Triggering a pin reset.");
+ NRF_LOG_FINAL_FLUSH();
+ nrf_gpio_cfg_output(BSP_SELF_PINRESET_PIN);
+ nrf_gpio_pin_clear(BSP_SELF_PINRESET_PIN);
+ break;
+ default:
+ break;
+ }
+}
+
+
+APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF(m_app_dfu,
+ NRF_DFU_TRIGGER_USB_INTERFACE_NUM,
+ &m_dfu_info,
+ m_version_string,
+ dfu_trigger_evt_handler);
+
+
+static void usbd_user_evt_handler(app_usbd_event_type_t event)
+{
+ switch (event)
+ {
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_disable();
+ break;
+ case APP_USBD_EVT_POWER_DETECTED:
+ NRF_LOG_INFO("USB power detected");
+
+ if (!nrf_drv_usbd_is_enabled())
+ {
+ app_usbd_enable();
+ }
+ break;
+ case APP_USBD_EVT_POWER_REMOVED:
+ NRF_LOG_INFO("USB power removed");
+ app_usbd_stop();
+ break;
+ case APP_USBD_EVT_POWER_READY:
+ NRF_LOG_INFO("USB ready");
+ app_usbd_start();
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void serial_number_strings_create(void)
+{
+ // Remove characters that are not supported in semantic versioning strings.
+ for (size_t i = strlen(APP_NAME) + 1; i < strlen((char*)m_version_string); i++)
+ {
+ if (((m_version_string[i] >= 'a') && (m_version_string[i] <= 'z'))
+ || ((m_version_string[i] >= 'A') && (m_version_string[i] <= 'Z'))
+ || ((m_version_string[i] >= '0') && (m_version_string[i] <= '9'))
+ || (m_version_string[i] == '+')
+ || (m_version_string[i] == '.')
+ || (m_version_string[i] == '-'))
+ {
+ // Valid semantic versioning character.
+ }
+ else
+ {
+ m_version_string[i] = '-';
+ }
+ }
+
+#if !NRF_DFU_TRIGGER_USB_USB_SHARED
+ app_usbd_serial_num_generate();
+#endif
+}
+
+#if !(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+static void usbd_evt_handler(app_usbd_internal_evt_t const * const p_event)
+{
+ app_usbd_event_execute(p_event);
+}
+#endif
+
+ret_code_t nrf_dfu_trigger_usb_init(void)
+{
+ ret_code_t ret;
+ static bool initialized = false;
+
+ if (initialized)
+ {
+ return NRF_SUCCESS;
+ }
+
+ m_dfu_info.wAddress = CODE_START;
+ m_dfu_info.wFirmwareSize = CODE_SIZE;
+ m_dfu_info.wVersionMajor = APP_VERSION_MAJOR;
+ m_dfu_info.wVersionMinor = APP_VERSION_MINOR;
+ m_dfu_info.wFirmwareID = APP_ID;
+ m_dfu_info.wFlashPageSize = DFU_FLASH_PAGE_SIZE;
+ m_dfu_info.wFlashSize = m_dfu_info.wFlashPageSize * DFU_FLASH_PAGE_COUNT;
+
+ serial_number_strings_create();
+
+ if (!NRF_DFU_TRIGGER_USB_USB_SHARED)
+ {
+ static const app_usbd_config_t usbd_config = {
+
+#if !(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+ .ev_handler = usbd_evt_handler,
+#endif
+ .ev_state_proc = usbd_user_evt_handler
+ };
+
+ ret = nrf_drv_clock_init();
+ if ((ret != NRF_SUCCESS) && (ret != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return ret;
+ }
+
+ ret = app_usbd_init(&usbd_config);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ app_usbd_class_inst_t const * class_dfu = app_usbd_nrf_dfu_trigger_class_inst_get(&m_app_dfu);
+ ret = app_usbd_class_append(class_dfu);
+
+ if (!NRF_DFU_TRIGGER_USB_USB_SHARED)
+ {
+ if (USBD_POWER_DETECTION)
+ {
+ ret = app_usbd_power_events_enable();
+ APP_ERROR_CHECK(ret);
+ }
+ else
+ {
+ NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");
+
+ app_usbd_enable();
+ app_usbd_start();
+ }
+ }
+
+ if (ret == NRF_SUCCESS)
+ {
+ initialized = true;
+ }
+
+ return ret;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h
new file mode 100644
index 0000000..c7ce4d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_DFU_TRIGGER_USB_H
+#define NRF_DFU_TRIGGER_USB_H
+
+#include "sdk_errors.h"
+
+/**
+ * @defgroup nrf_dfu_trigger_usb USB DFU trigger library
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52840 USB DFU trigger library is used to enter the bootloader and read the firmware version.
+ *
+ * @details See @ref lib_dfu_trigger_usb for additional documentation.
+ * @{
+ */
+
+/**
+ * @brief Function for initializing the USB DFU trigger library.
+ *
+ * @note If the USB is also used for other purposes, then this function must be called after USB is
+ * initialized but before it is enabled. In this case, the configuration flag @ref
+ * NRF_DFU_TRIGGER_USB_USB_SHARED must be set to 1.
+ *
+ * @note Calling this again after the first success has no effect and returns @ref NRF_SUCCESS.
+ *
+ * @note If @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE is on (1), USB events must be handled manually.
+ * See @ref app_usbd_event_queue_process.
+ *
+ * @retval NRF_SUCCESS On successful initialization.
+ * @return An error code on failure, for example if called at a wrong time.
+ */
+ret_code_t nrf_dfu_trigger_usb_init(void);
+
+/** @} */
+
+#endif //NRF_DFU_TRIGGER_USB_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h
new file mode 100644
index 0000000..5ccd290
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h
@@ -0,0 +1,302 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_types DFU types
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_TYPES_H__
+#define NRF_DFU_TYPES_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf.h"
+#include "nrf_mbr.h"
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+#include "ble_gap.h"
+#define SYSTEM_SERVICE_ATT_SIZE 8 /**< Size of the system service attribute length including CRC-16 at the end. */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define INIT_COMMAND_MAX_SIZE 256 /**< Maximum size of the init command stored in dfu_settings. */
+
+/** @brief Size of a flash page. This value is used for calculating the size of the reserved
+ * flash space in the bootloader region.
+ */
+#if defined(NRF51)
+ #define CODE_PAGE_SIZE (PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
+#elif defined(NRF52) || defined(NRF52840_XXAA)
+ #define CODE_PAGE_SIZE (MBR_PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
+#else
+ #error "Architecture not set."
+#endif
+
+/** @brief Maximum size of a data object.*/
+#if defined(NRF51)
+ #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE * 4)
+#elif defined(NRF52_SERIES) || defined (__SDK_DOXYGEN__)
+ #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE)
+#else
+ #error "Architecture not set."
+#endif
+
+/** @brief Page location of the bootloader settings address.
+ */
+#if defined (NRF51)
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0003FC00UL)
+#elif defined( NRF52810_XXAA )
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0002F000UL)
+#elif defined( NRF52832_XXAA )
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0007F000UL)
+#elif defined(NRF52840_XXAA)
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x000FF000UL)
+#else
+ #error No valid target set for BOOTLOADER_SETTINGS_ADDRESS.
+#endif
+
+#define BOOTLOADER_SETTINGS_PAGE_SIZE (CODE_PAGE_SIZE)
+
+/**
+ * @brief MBR parameters page in UICR.
+ *
+ * Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR).
+ *
+ * @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set.
+ */
+#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18)
+#define NRF_MBR_PARAMS_PAGE_SIZE (CODE_PAGE_SIZE)
+
+/** @brief Page location of the MBR parameters page address.
+ */
+#if defined(NRF52840_XXAA) || defined(NRF52840_XXAA_ENGA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x000FE000UL)
+#elif defined(NRF52832_XXAA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0007E000UL)
+#elif defined(NRF52810_XXAA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0002E000UL)
+#endif
+
+/** @brief Size (in bytes) of the flash area reserved for application data.
+ *
+ * The area is found at the end of the application area, next to the start of
+ * the bootloader. This area will not be erased by the bootloader during a
+ * firmware upgrade. The default value is 3 pages which matches the size used
+ * in most SDK examples.
+ */
+#ifndef DFU_APP_DATA_RESERVED
+#define DFU_APP_DATA_RESERVED (CODE_PAGE_SIZE * 3)
+#endif
+
+/** @brief Total size of the region between the SoftDevice and the bootloader.
+ */
+#define DFU_REGION_END(bootloader_start_addr) ((bootloader_start_addr) - (DFU_APP_DATA_RESERVED))
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#define DFU_REGION_START (nrf_dfu_bank0_start_addr())
+#else
+#define DFU_REGION_START (MBR_SIZE)
+#endif
+
+#define DFU_REGION_TOTAL_SIZE ((DFU_REGION_END) - (DFU_REGION_START))
+
+#define NRF_DFU_CURRENT_BANK_0 0x00
+#define NRF_DFU_CURRENT_BANK_1 0x01
+
+#define NRF_DFU_BANK_LAYOUT_DUAL 0x00
+#define NRF_DFU_BANK_LAYOUT_SINGLE 0x01
+
+/** @brief DFU bank state codes.
+ *
+ * @details The DFU bank state indicates the content of a bank:
+ * A valid image of a certain type or an invalid image.
+ */
+
+#define NRF_DFU_BANK_INVALID 0x00 /**< Invalid image. */
+#define NRF_DFU_BANK_VALID_APP 0x01 /**< Valid application. */
+#define NRF_DFU_BANK_VALID_SD 0xA5 /**< Valid SoftDevice. */
+#define NRF_DFU_BANK_VALID_BL 0xAA /**< Valid bootloader. */
+#define NRF_DFU_BANK_VALID_SD_BL 0xAC /**< Valid SoftDevice and bootloader. */
+
+/** @brief Description of a single bank. */
+#pragma pack(4)
+typedef struct
+{
+ uint32_t image_size; /**< Size of the image in the bank. */
+ uint32_t image_crc; /**< CRC of the image. If set to 0, the CRC is ignored. */
+ uint32_t bank_code; /**< Identifier code for the bank. */
+} nrf_dfu_bank_t;
+
+/**@brief DFU progress.
+ *
+ * Be aware of the difference between objects and firmware images. A firmware image consists of multiple objects, each of a maximum size @ref DATA_OBJECT_MAX_SIZE.
+ *
+ * @note The union inside this struct is cleared when CREATE_OBJECT of command type is executed, and when there is a valid post-validation.
+ * In DFU activation (after reset) the @ref dfu_progress_t::update_start_address will be used in case of a SD/SD+BL update.
+ */
+ANON_UNIONS_ENABLE;
+typedef struct
+{
+ uint32_t command_size; /**< The size of the current init command stored in the DFU settings. */
+ uint32_t command_offset; /**< The offset of the currently received init command data. The offset will increase as the init command is received. */
+ uint32_t command_crc; /**< The calculated CRC of the init command (calculated after the transfer is completed). */
+ uint32_t data_object_size; /**< The size of the last object created. Note that this size is not the size of the whole firmware image.*/
+ union
+ {
+ struct
+ {
+ uint32_t firmware_image_crc; /**< CRC value of the current firmware (continuously calculated as data is received). */
+ uint32_t firmware_image_crc_last; /**< The CRC of the last executed object. */
+ uint32_t firmware_image_offset; /**< The offset of the current firmware image being transferred. Note that this offset is the offset in the entire firmware image and not only the current object. */
+ uint32_t firmware_image_offset_last;/**< The offset of the last executed object from the start of the firmware image. */
+ };
+ struct
+ {
+ uint32_t update_start_address; /**< Value indicating the start address of the new firmware (before copy). It's always used, but it's most important for an SD/SD+BL update where the SD changes size or if the DFU process had a power loss when updating a SD with changed size. */
+ };
+ };
+} dfu_progress_t;
+ANON_UNIONS_DISABLE;
+
+/** @brief Event types in the bootloader and DFU process. */
+typedef enum
+{
+ NRF_DFU_EVT_DFU_INITIALIZED, /**< Starting DFU. */
+ NRF_DFU_EVT_TRANSPORT_ACTIVATED, /**< Transport activated (e.g. BLE connected, USB plugged in). */
+ NRF_DFU_EVT_TRANSPORT_DEACTIVATED, /**< Transport deactivated (e.g. BLE disconnected, USB plugged out). */
+ NRF_DFU_EVT_DFU_STARTED, /**< DFU process started. */
+ NRF_DFU_EVT_OBJECT_RECEIVED, /**< A DFU data object has been received. */
+ NRF_DFU_EVT_DFU_FAILED, /**< DFU process has failed, been interrupted, or hung. */
+ NRF_DFU_EVT_DFU_COMPLETED, /**< DFU process completed. */
+ NRF_DFU_EVT_DFU_ABORTED, /**< DFU process aborted. */
+} nrf_dfu_evt_type_t;
+
+/**
+ * @brief Function for notifying DFU state.
+ */
+typedef void (*nrf_dfu_observer_t)(nrf_dfu_evt_type_t notification);
+
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+
+typedef struct
+{
+ uint32_t crc; /**< CRC of the rest of the parameters in this struct. */
+ ble_gap_id_key_t ble_id; /**< BLE GAP identity key of the device that initiated the DFU process. */
+ ble_gap_enc_key_t enc_key; /**< Encryption key structure containing encrypted diversifier and LTK for reestablishing the bond. */
+ uint8_t sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */
+} nrf_dfu_peer_data_t;
+
+typedef enum
+{
+ DFU_PEER_DATA_STATE_INVALID = 0,
+ DFU_PEER_DATA_STATE_INITIALIZED = 1,
+ DFU_PEER_DATA_STATE_WRITE_REQUESTED = 2,
+ DFU_PEER_DATA_STATE_WRITE_FINISHED = 3,
+ DFU_PEER_DATA_STATE_WRITE_FAILED = 4,
+} nrf_dfu_peer_data_state_t;
+
+typedef struct
+{
+ uint32_t crc; /**< CRC of the rest of the parameters in this struct. Calculated by the bootloader. */
+ uint8_t name[20]; /**< New advertisement name to set. */
+ uint32_t len; /**< Length of the advertisement name. */
+} nrf_dfu_adv_name_t;
+
+typedef enum
+{
+ DFU_ADV_NAME_STATE_INVALID = 0,
+ DFU_ADV_NAME_STATE_INITIALIZED = 1,
+ DFU_ADV_NAME_STATE_WRITE_REQUESTED = 2,
+ DFU_ADV_NAME_STATE_WRITE_FINISHED = 3,
+ DFU_ADV_NAME_STATE_WRITE_FAILED = 4,
+} nrf_dfu_set_adv_name_state_t;
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+
+/**@brief DFU settings for application and bank data.
+ */
+typedef struct
+{
+ uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */
+ uint32_t settings_version; /**< Version of the current DFU settings struct layout. */
+ uint32_t app_version; /**< Version of the last stored application. */
+ uint32_t bootloader_version; /**< Version of the last stored bootloader. */
+
+ uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */
+ uint32_t bank_current; /**< The bank that is currently used. */
+
+ nrf_dfu_bank_t bank_0; /**< Bank 0. */
+ nrf_dfu_bank_t bank_1; /**< Bank 1. */
+
+ uint32_t write_offset; /**< Write offset for the current operation. */
+ uint32_t sd_size; /**< Size of the SoftDevice. */
+
+ dfu_progress_t progress; /**< Current DFU progress. */
+
+ uint32_t enter_buttonless_dfu;
+ uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+ nrf_dfu_peer_data_t peer_data; /**< Not included in calculated CRC. */
+ nrf_dfu_adv_name_t adv_name; /**< Not included in calculated CRC. */
+#endif // NRF_DFU_TRANSPORT_BLE
+
+} nrf_dfu_settings_t;
+
+#pragma pack() // revert pack settings
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_TYPES_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c
new file mode 100644
index 0000000..286eea6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_utils.h"
+
+#include "nrf_dfu_settings.h"
+#include "nrf_bootloader_info.h"
+#include "crc32.h"
+#include "nrf_log.h"
+
+void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank)
+{
+ // Set the bank-code to invalid, and reset size/CRC
+ memset(p_bank, 0, sizeof(nrf_dfu_bank_t));
+
+ // Reset write pointer after completed operation
+ s_dfu_settings.write_offset = 0;
+}
+
+
+#ifndef BLE_STACK_SUPPORT_REQD
+void nrf_dfu_softdevice_invalidate(void)
+{
+ static const uint32_t all_zero = 0UL;
+
+ if (SD_PRESENT)
+ {
+ ret_code_t err_code = nrf_dfu_flash_store(SD_MAGIC_NUMBER_ABS_OFFSET_GET(MBR_SIZE), &all_zero, 4, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not invalidate SoftDevice.")
+ }
+ else
+ {
+ // If there is an app it must be invalidated since its start address can no longer be resolved.
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
+ {
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
+ }
+ // Since the start of bank 0 has now implicitly been moved to the start
+ // of the invalidated SoftDevice, its image size must be increased by the
+ // same amount so the start of bank 1 will be correctly calculated.
+ s_dfu_settings.bank_0.image_size += SD_SIZE_GET(MBR_SIZE) - MBR_SIZE;
+ }
+ }
+}
+#endif
+
+
+uint32_t nrf_dfu_bank0_start_addr(void)
+{
+ if (SD_PRESENT)
+ {
+ return ALIGN_TO_PAGE(SD_SIZE_GET(MBR_SIZE));
+ }
+ else
+ {
+ return MBR_SIZE;
+ }
+}
+
+
+uint32_t nrf_dfu_bank1_start_addr(void)
+{
+ uint32_t bank0_addr = nrf_dfu_bank0_start_addr();
+ return ALIGN_TO_PAGE(bank0_addr + s_dfu_settings.bank_0.image_size);
+}
+
+
+uint32_t nrf_dfu_app_start_address(void)
+{
+ return nrf_dfu_bank0_start_addr();
+}
+
+
+uint32_t nrf_dfu_softdevice_start_address(void)
+{
+ return MBR_SIZE;
+}
+
+
+bool nrf_dfu_app_is_valid(bool do_crc)
+{
+ NRF_LOG_DEBUG("Enter nrf_dfu_app_is_valid");
+ if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
+ {
+ // Bank 0 has no valid app. Nothing to boot
+ NRF_LOG_DEBUG("Return false in valid app check");
+ return false;
+ }
+
+ // If CRC == 0, the CRC check is skipped.
+ if (do_crc && (s_dfu_settings.bank_0.image_crc != 0))
+ {
+ uint32_t crc = crc32_compute((uint8_t*) nrf_dfu_app_start_address(),
+ s_dfu_settings.bank_0.image_size,
+ NULL);
+
+ if (crc != s_dfu_settings.bank_0.image_crc)
+ {
+ // CRC does not match with what is stored.
+ NRF_LOG_DEBUG("Return false in CRC");
+ return false;
+ }
+ }
+
+ NRF_LOG_DEBUG("Return true. App was valid");
+ return true;
+}
+
+
+
+uint32_t nrf_dfu_cache_prepare(const uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice)
+{
+ ret_code_t err_code;
+ bool cache_too_small;
+ enum
+ {
+ INITIAL_DELETE_APP = 0,
+ APP_DELETED_DELETE_SOFTDEVICE = 1,
+ SOFTDEVICE_DELETED = 2
+ } pass;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_cache_prepare()");
+ NRF_LOG_DEBUG("required_size: 0x%x.", required_size);
+ NRF_LOG_DEBUG("single_bank: %s.", single_bank ? "true" : "false");
+ NRF_LOG_DEBUG("keep_app: %s.", keep_app ? "true" : "false");
+ NRF_LOG_DEBUG("keep_softdevice: %s.", keep_softdevice ? "true" : "false");
+ NRF_LOG_DEBUG("SD_PRESENT: %s.", SD_PRESENT ? "true" : "false");
+ NRF_LOG_DEBUG("Bank contents:");
+ NRF_LOG_DEBUG("Bank 0 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_0.bank_code, s_dfu_settings.bank_0.image_size);
+ NRF_LOG_DEBUG("Bank 1 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_1.bank_code, s_dfu_settings.bank_1.image_size);
+
+ // Pass 0 deletes the app if necessary or requested, and if so, proceeds to pass 1.
+ // Pass 1 deletes the SoftDevice if necessary or requested, and if so, proceeds to pass 2.
+ // Pass 2 does a last size check.
+ for (pass = INITIAL_DELETE_APP; pass <= SOFTDEVICE_DELETED; pass++)
+ {
+ uint32_t cache_address;
+ const uint32_t bootloader_start_addr = BOOTLOADER_START_ADDR; // Assign to a variable to prevent warning in Keil 4.
+ bool keep_firmware = true;
+ bool delete_more;
+
+ switch (pass)
+ {
+ case INITIAL_DELETE_APP:
+ cache_address = nrf_dfu_bank1_start_addr();
+
+ // If there is no app, keep_app should be assumed false, so we can free up more space.
+ keep_firmware = keep_app && (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP);
+ break;
+
+ case APP_DELETED_DELETE_SOFTDEVICE:
+ cache_address = nrf_dfu_bank0_start_addr();
+
+ // If there is no SoftDevice, keep_SoftDevice should be assumed true, because there is
+ // no point to continuing since the SoftDevice is the last firmware that can be deleted.
+ keep_firmware = keep_softdevice || !SD_PRESENT;
+ break;
+
+ case SOFTDEVICE_DELETED:
+ cache_address = nrf_dfu_softdevice_start_address();
+ break;
+
+ default:
+ ASSERT(false);
+ cache_address = 0;
+ break;
+ }
+
+ ASSERT(cache_address <= DFU_REGION_END(bootloader_start_addr));
+ cache_too_small = required_size > (DFU_REGION_END(bootloader_start_addr) - cache_address);
+ delete_more = cache_too_small || single_bank; // Delete app or SoftDevice only if we need more room, or if single bank is requested.
+
+ NRF_LOG_DEBUG("pass: %d.", pass);
+ NRF_LOG_DEBUG("cache_address: 0x%x.", cache_address);
+ NRF_LOG_DEBUG("cache_too_small: %s.", cache_too_small ? "true" : "false");
+ NRF_LOG_DEBUG("keep_firmware: %s.", keep_firmware ? "true" : "false");
+ NRF_LOG_DEBUG("delete_more: %s.", delete_more ? "true" : "false");
+
+ if (!delete_more || keep_firmware || (pass >= SOFTDEVICE_DELETED))
+ {
+ // Stop, done.
+ break;
+ }
+ }
+
+ if (cache_too_small)
+ {
+ NRF_LOG_WARNING("Aborting. Cannot fit new firmware on device");
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ // Room was found. Make the necessary preparations for receiving update.
+
+#ifndef BLE_STACK_SUPPORT_REQD
+ if (pass >= SOFTDEVICE_DELETED)
+ {
+ NRF_LOG_DEBUG("Invalidating SoftDevice.");
+ nrf_dfu_softdevice_invalidate();
+ }
+#endif
+ if (pass >= APP_DELETED_DELETE_SOFTDEVICE)
+ {
+ NRF_LOG_DEBUG("Invalidating app.");
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
+ }
+
+ s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
+ s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
+
+ // Prepare bank for new image.
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
+
+ // Store the Firmware size in the bank for continuations
+ s_dfu_settings.bank_1.image_size = required_size;
+
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h
new file mode 100644
index 0000000..6369f92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_utils DFU utilities
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_UTILS_H__
+#define NRF_DFU_UTILS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Round up val to the next page boundary
+ */
+#define ALIGN_TO_PAGE(val) ALIGN_NUM((CODE_PAGE_SIZE), (val))
+
+
+/** @brief Function for getting the start address of bank 0.
+ *
+ * @note Bank 0 starts after the SoftDevice if a SoftDevice is present.
+ *
+ * @return The start address of bank 0.
+ */
+uint32_t nrf_dfu_bank0_start_addr(void);
+
+
+/** @brief Function for getting the start address of bank 1.
+ *
+ * @return The start address of bank 1.
+ */
+uint32_t nrf_dfu_bank1_start_addr(void);
+
+
+/** @brief Function for getting the start address of the app.
+ *
+ * @return The start address of the bootable app.
+ */
+uint32_t nrf_dfu_app_start_address(void);
+
+
+/** @brief Function for getting the start address of the SoftDevice.
+ *
+ * @return The start address of the SoftDevivce.
+ */
+uint32_t nrf_dfu_softdevice_start_address(void);
+
+
+/** @brief Function for checking if the main application is valid.
+ *
+ * @details This function checks if there is a valid application
+ * located at Bank 0.
+ *
+ * @param[in] do_crc Perform CRC check on application.
+ *
+ * @retval true If a valid application has been detected.
+ * @retval false If there is no valid application.
+ */
+bool nrf_dfu_app_is_valid(bool do_crc);
+
+
+/** @brief Function for finding and preparing a place in flash in which to store a DFU update.
+ *
+ * @details This function checks the size requirements and selects a location for
+ * placing the cache of the DFU images.
+ * The function tries to find enough space after the existing firmwares. If there is not
+ * enough space, the present application is deleted. If there is still not enough space,
+ * the SoftDevice is deleted.
+ * If @p single_bank is true, the default behavior is to immediately delete the app and
+ * SoftDevice as necessary to place the new firmware at its intended location. If the
+ * intended location cannot be made available, or if the update is a bootloader update,
+ * the update will be a dual bank update, and nothing will be deleted by this function
+ * except when needed for size.
+ * If @p keep_app is true, the app is never deleted by this function. Likewise if @p
+ * keep_softdevice is true, the SoftDevice is never deleted by this function.
+ * If the new firmware cannot fit within the constraints, nothing is deleted and the
+ * function fails.
+ *
+ * @param[in] required_size Requirements for the size of the new image.
+ * @param[in] single_bank Whether to put the firmware directly where it's meant to go.
+ * @p keep_app and @p keep_softdevice take precedence over this.
+ * @param[in] keep_app True to ensure the app is not deleted by this function. This
+ * effectively enforces dual bank update.
+ * @param[out] keep_softdevice True to ensure the SoftDevice is not deleted by this function.
+ *
+ * @retval NRF_SUCCESS If a cache location was found for the DFU process.
+ * @retval NRF_ERROR_NO_MEM If there is not enough space available to receive the update.
+ * Nothing has been deleted.
+ */
+uint32_t nrf_dfu_cache_prepare(uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice);
+
+
+/**@brief Function for making sure a SoftDevice is not recognized as such anymore.
+ *
+ * @details It works by overwriting the magic number of the SoftDevice with 0s. The
+ * magic number is used throughout the bootloader to detect whether a SoftDevice
+ * is present.
+ *
+ * @warning This function should only be called when both banks are already invalid.
+ * because the (implicit) position of the banks will shift when the SoftDevice
+ * is invalidated.
+ */
+void nrf_dfu_softdevice_invalidate(void);
+
+
+/**@brief Function for making sure a bank is not copied or booted.
+ *
+ * @details This also sets the size of the bank to 0.
+ *
+ * @param[in] p_bank Pointer to the bank to be invalidated.
+ */
+void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_UTILS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c
new file mode 100644
index 0000000..566702d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c
@@ -0,0 +1,745 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_bootloader_info.h"
+#include "pb.h"
+#include "pb_common.h"
+#include "pb_decode.h"
+#include "dfu-cc.pb.h"
+#include "crc32.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "nrf_dfu_validation.h"
+#include "nrf_dfu_ver_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_validation
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#ifndef NRF_DFU_DEBUG
+#ifdef NRF_DFU_DEBUG_VERSION
+#define NRF_DFU_DEBUG 1
+#else
+#define NRF_DFU_DEBUG 0
+#endif
+#endif
+
+#ifndef DFU_REQUIRES_SOFTDEVICE
+#ifndef BLE_STACK_SUPPORT_REQD
+#define DFU_REQUIRES_SOFTDEVICE 0
+#else
+#define DFU_REQUIRES_SOFTDEVICE 1
+#endif
+#endif
+
+#define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
+
+/* Whether a complete init command has been received and prevalidated, but the firmware
+ * is not yet fully transferred. This value will also be correct after reset.
+ */
+static bool m_valid_init_cmd_present = false;
+static dfu_packet_t m_packet = DFU_PACKET_INIT_DEFAULT;
+static uint8_t* m_init_packet_data_ptr = 0;
+static uint32_t m_init_packet_data_len = 0;
+static pb_istream_t m_pb_stream;
+
+static nrf_crypto_ecdsa_verify_context_t m_verify_context = {0};
+
+static nrf_crypto_hash_context_t m_hash_context = {0};
+
+
+__ALIGN(4) extern const uint8_t pk[64];
+
+/** @brief Value length structure holding the public key.
+ *
+ * @details The pk value pointed to is the public key present in dfu_public_key.c
+ */
+static nrf_crypto_ecc_public_key_t m_public_key;
+
+/** @brief Structure to hold a signature
+ */
+static nrf_crypto_ecdsa_secp256r1_signature_t m_signature;
+
+/** @brief Structure to hold the hash for the init packet
+ */
+static nrf_crypto_hash_sha256_digest_t m_init_packet_hash;
+
+/** @brief Structure to hold the hash for the firmware image
+ */
+static nrf_crypto_hash_sha256_digest_t m_fw_hash;
+
+
+static void pb_decoding_callback(pb_istream_t *str, uint32_t tag, pb_wire_type_t wire_type, void *iter)
+{
+ pb_field_iter_t* p_iter = (pb_field_iter_t *) iter;
+
+ // match the beginning of the init command
+ if (p_iter->pos->ptr == &dfu_init_command_fields[0])
+ {
+ uint8_t * ptr = (uint8_t *)str->state;
+ uint32_t size = str->bytes_left;
+
+ // remove tag byte
+ ptr++;
+ size--;
+
+ // store the info in init_packet_data
+ m_init_packet_data_ptr = ptr;
+ m_init_packet_data_len = size;
+
+ NRF_LOG_DEBUG("PB: Init packet data len: %d", size);
+ }
+}
+
+/** @brief Function for decoding byte stream into variable.
+ *
+ * @retval true If the stored init command was successfully decoded.
+ * @retval false If there was no stored init command, or the decoding failed.
+ */
+static bool stored_init_cmd_decode(void)
+{
+ m_pb_stream = pb_istream_from_buffer(s_dfu_settings.init_command,
+ s_dfu_settings.progress.command_size);
+
+ // Attach our callback to follow the field decoding
+ m_pb_stream.decoding_callback = pb_decoding_callback;
+
+ m_init_packet_data_ptr = NULL;
+ m_init_packet_data_len = 0;
+
+ if (!pb_decode(&m_pb_stream, dfu_packet_fields, &m_packet))
+ {
+ NRF_LOG_ERROR("Handler: Invalid protocol buffer m_pb_stream");
+ return false;
+ }
+
+ return true;
+}
+
+
+void nrf_dfu_validation_init(void)
+{
+ ret_code_t err_code;
+
+ // If the command is stored to flash, init command was valid.
+ if ( (s_dfu_settings.progress.command_size != 0)
+ && stored_init_cmd_decode()
+ && (s_dfu_settings.bank_1.image_size != 0))
+ {
+ m_valid_init_cmd_present = true;
+ }
+ else
+ {
+ m_valid_init_cmd_present = false;
+ }
+
+ err_code = nrf_crypto_init();
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_PARAMETER(err_code);
+
+
+ err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ &m_public_key,
+ pk,
+ sizeof(pk));
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_PARAMETER(err_code);
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if (size == 0)
+ {
+ ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ }
+ else if (size > INIT_COMMAND_MAX_SIZE)
+ {
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ // Set DFU to uninitialized.
+ m_valid_init_cmd_present = false;
+
+ // Reset all progress.
+ s_dfu_settings.write_offset = 0;
+ memset(&s_dfu_settings.progress, 0x00, sizeof(dfu_progress_t));
+
+ // Set the init command size.
+ s_dfu_settings.progress.command_size = size;
+ }
+ return ret_val;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if ((length + s_dfu_settings.progress.command_offset) > s_dfu_settings.progress.command_size)
+ {
+ NRF_LOG_ERROR("Init command larger than expected.");
+ ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ }
+ else
+ {
+ // Copy the received data to RAM, update offset and calculate CRC.
+ memcpy(&s_dfu_settings.init_command[s_dfu_settings.progress.command_offset],
+ p_data,
+ length);
+
+ s_dfu_settings.progress.command_offset += length;
+ s_dfu_settings.progress.command_crc = crc32_compute(p_data,
+ length,
+ &s_dfu_settings.progress.command_crc);
+ }
+ return ret_val;
+}
+
+
+void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
+ uint32_t * p_crc,
+ uint32_t * p_max_size)
+{
+ *p_offset = s_dfu_settings.progress.command_offset;
+ *p_crc = s_dfu_settings.progress.command_crc;
+ *p_max_size = INIT_COMMAND_MAX_SIZE;
+}
+
+
+bool nrf_dfu_validation_init_cmd_present(void)
+{
+ return m_valid_init_cmd_present;
+}
+
+
+// Function determines if init command signature is obligatory
+static bool signature_required(dfu_fw_type_t fw_type_to_be_updated)
+{
+ bool result = true;
+
+ if ((!DFU_REQUIRES_SOFTDEVICE && (fw_type_to_be_updated == DFU_FW_TYPE_SOFTDEVICE)) ||
+ (fw_type_to_be_updated == DFU_FW_TYPE_APPLICATION))
+ {
+ result = NRF_DFU_REQUIRE_SIGNED_APP_UPDATE;
+ }
+ return result;
+}
+
+
+// Function to perform signature check if required.
+static nrf_dfu_result_t signature_check(dfu_fw_type_t fw_type,
+ dfu_signature_type_t signature_type,
+ dfu_signed_command_signature_t const * p_signature)
+{
+ ret_code_t err_code;
+ size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ if (!signature_required(fw_type))
+ {
+ return NRF_DFU_RES_CODE_SUCCESS;
+ }
+
+ NRF_LOG_INFO("Signature required. Checking signature.")
+ if (p_signature == NULL)
+ {
+ NRF_LOG_WARNING("No signature found.");
+ return EXT_ERR(NRF_DFU_EXT_ERROR_SIGNATURE_MISSING);
+ }
+
+ if (signature_type != DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256)
+ {
+ NRF_LOG_INFO("Invalid signature type");
+ return EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE);
+ }
+
+ NRF_LOG_INFO("Calculating init packet hash (init packet len: %d)", m_init_packet_data_len);
+ err_code = nrf_crypto_hash_calculate(&m_hash_context,
+ &g_nrf_crypto_hash_sha256_info,
+ m_init_packet_data_ptr,
+ m_init_packet_data_len,
+ m_init_packet_hash,
+ &hash_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+
+ if (sizeof(m_signature) != p_signature->size)
+ {
+ return NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+
+ // Prepare the signature received over the air.
+ memcpy(m_signature, p_signature->bytes, p_signature->size);
+
+ // calculate the signature
+ NRF_LOG_INFO("Verify signature");
+ err_code = nrf_crypto_ecdsa_verify(&m_verify_context,
+ &m_public_key,
+ m_init_packet_hash,
+ hash_len,
+ m_signature,
+ sizeof(m_signature));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code);
+ NRF_LOG_DEBUG("Signature:");
+ NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature));
+ NRF_LOG_DEBUG("Hash:");
+ NRF_LOG_HEXDUMP_DEBUG(m_init_packet_hash, hash_len);
+ NRF_LOG_DEBUG("Public Key:");
+ NRF_LOG_HEXDUMP_DEBUG(pk, sizeof(pk));
+ NRF_LOG_FLUSH();
+
+ return NRF_DFU_RES_CODE_INVALID_OBJECT;
+ }
+
+ NRF_LOG_INFO("Image verified");
+ return NRF_DFU_RES_CODE_SUCCESS;
+}
+
+
+// Function to calculate the total size of the firmware(s) in the update.
+static nrf_dfu_result_t update_data_size_get(dfu_init_command_t const * p_init, uint32_t * p_size)
+{
+ nrf_dfu_result_t ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ uint32_t fw_sz = 0;
+
+ if ((p_init->type == DFU_FW_TYPE_APPLICATION) && (p_init->has_app_size == true))
+ {
+ fw_sz = p_init->app_size;
+ }
+ else
+ {
+ if ((p_init->type & DFU_FW_TYPE_SOFTDEVICE) && (p_init->has_sd_size == true))
+ {
+ fw_sz = p_init->sd_size;
+ }
+
+ if ((p_init->type & DFU_FW_TYPE_BOOTLOADER) && (p_init->has_bl_size == true))
+ {
+ if (p_init->bl_size <= BOOTLOADER_SIZE)
+ {
+ fw_sz += p_init->bl_size;
+ }
+ else
+ {
+ NRF_LOG_ERROR("BL size (%d) over limit (%d)", p_init->bl_size, BOOTLOADER_SIZE);
+ fw_sz = 0;
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ }
+ }
+
+ if (fw_sz)
+ {
+ *p_size = fw_sz;
+ ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ }
+ else
+ {
+ NRF_LOG_ERROR("Init packet does not contain valid firmware size");
+ }
+
+ return ret_val;
+}
+
+
+/**
+ * @brief Function to check if single bank update should be used.
+ *
+ * @param new_fw_type Firmware type.
+ */
+static bool use_single_bank(dfu_fw_type_t new_fw_type)
+{
+ bool result = false;
+
+ if (((new_fw_type == DFU_FW_TYPE_APPLICATION) || (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)) &&
+ NRF_DFU_SINGLE_BANK_APP_UPDATES)
+ {
+ result = true;
+ }
+
+ return result;
+}
+
+
+// Function to determine if the new firmware needs a SoftDevice to be present.
+static bool update_requires_softdevice(dfu_init_command_t const * p_init)
+{
+ return ((p_init->sd_req_count > 0) && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD));
+}
+
+
+// Function to determine if the SoftDevice can be removed during the update or not.
+static bool keep_softdevice(dfu_init_command_t const * p_init)
+{
+ UNUSED_PARAMETER(p_init); // It's unused when DFU_REQUIRES_SOFTDEVICE is true.
+ return DFU_REQUIRES_SOFTDEVICE || update_requires_softdevice(p_init);
+}
+
+
+/**@brief Function to determine where to temporarily store the incoming firmware.
+ * This also checks whether the update will fit, and deletes existing
+ * firmware to make room for the new firmware.
+ *
+ * @param[in] p_init Init command.
+ * @param[in] fw_size The size of the incoming firmware.
+ * @param[out] p_addr The address at which to initially store the firmware.
+ *
+ * @retval NRF_DFU_RES_CODE_SUCCESS If the size check passed and
+ * an address was found.
+ * @retval NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES If the size check failed.
+ */
+static nrf_dfu_result_t update_data_addr_get(dfu_init_command_t const * p_init,
+ uint32_t fw_size,
+ uint32_t * p_addr)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ ret_code_t err_code = nrf_dfu_cache_prepare(fw_size,
+ use_single_bank(p_init->type),
+ NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES,
+ keep_softdevice(p_init));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Can't find room for update");
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ *p_addr = nrf_dfu_bank1_start_addr();
+ NRF_LOG_DEBUG("Write address set to 0x%08x", *p_addr);
+ }
+ return ret_val;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
+ uint32_t * p_data_len)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+
+ if (s_dfu_settings.progress.command_offset != s_dfu_settings.progress.command_size)
+ {
+ // The object wasn't the right (requested) size
+ NRF_LOG_ERROR("Execute with faulty offset");
+ ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ }
+ else if (m_valid_init_cmd_present)
+ {
+ *p_dst_data_addr = nrf_dfu_bank1_start_addr();
+ *p_data_len = s_dfu_settings.bank_1.image_size;
+ ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ }
+ else if (stored_init_cmd_decode() &&
+ (m_packet.has_signed_command || m_packet.has_command))
+ {
+ dfu_command_t const * p_command = &m_packet.command;
+ dfu_signature_type_t signature_type = (dfu_signature_type_t) 0; // Placeholder.
+ dfu_signed_command_signature_t * p_signature = NULL;
+
+ *p_dst_data_addr = 0;
+ *p_data_len = 0;
+
+ if (m_packet.has_signed_command)
+ {
+ p_command = &m_packet.signed_command.command;
+ signature_type = m_packet.signed_command.signature_type;
+ p_signature = &m_packet.signed_command.signature;
+ }
+
+ // Validate signature.
+ ret_val = signature_check(p_command->init.type, signature_type, p_signature);
+
+ // Validate versions
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = nrf_dfu_ver_validation_check(&p_command->init);
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ m_valid_init_cmd_present = true;
+ }
+ }
+
+ // Get size of binary
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = update_data_size_get(&p_command->init, p_data_len);
+ }
+
+ //Get address where to flash the binary
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = update_data_addr_get(&p_command->init, *p_data_len, p_dst_data_addr);
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Failed to decode init packet");
+ ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ }
+
+ return ret_val;
+}
+
+
+// Function to check the hash received in the init command against the received firmware.
+static bool fw_hash_ok(dfu_init_command_t const * p_init, uint32_t fw_start_addr, uint32_t fw_size)
+{
+ ret_code_t err_code;
+ bool result = true;
+ size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ ASSERT(p_init != NULL);
+
+ NRF_LOG_DEBUG("Hash verification. Firmware start address: 0x%x, size: 0x%x", fw_start_addr, fw_size);
+ err_code = nrf_crypto_hash_calculate(&m_hash_context,
+ &g_nrf_crypto_hash_sha256_info,
+ (uint8_t*)fw_start_addr,
+ fw_size,
+ m_fw_hash,
+ &hash_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code);
+ result = false;
+ }
+ else if (memcmp(m_fw_hash, p_init->hash.hash.bytes, NRF_CRYPTO_HASH_SIZE_SHA256) != 0)
+ {
+ NRF_LOG_WARNING("Hash verification failed.");
+ NRF_LOG_DEBUG("Expected FW hash:")
+ NRF_LOG_HEXDUMP_DEBUG(p_init->hash.hash.bytes, NRF_CRYPTO_HASH_SIZE_SHA256);
+ NRF_LOG_DEBUG("Actual FW hash:")
+ NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
+ NRF_LOG_FLUSH();
+
+ result = false;
+ }
+
+ return result;
+}
+
+
+// Function to check if the update contains a SoftDevice and, if so, if it is of a different
+// major version than the existing SoftDevice.
+static bool is_major_softdevice_update(uint32_t new_sd_addr)
+{
+ // True if there is no SD right now, but there is a new one coming. This counts as a major update.
+ bool result = !SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER);
+
+ if (SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER))
+ {
+ // Both SoftDevices are present.
+ uint32_t current_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(MBR_SIZE));
+ uint32_t new_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(new_sd_addr));
+
+ result = (current_SD_major != new_SD_major);
+
+ NRF_LOG_INFO("SoftDevice update is a %s version update. Current: %d. New: %d.",
+ result ? "major" : "minor",
+ current_SD_major,
+ new_SD_major);
+ }
+
+ return result;
+}
+
+
+/**@brief Validate the SoftDevice size and magic number in structure found at 0x2000 in received SoftDevice.
+ *
+ * @param[in] sd_start_addr Start address of received SoftDevice.
+ * @param[in] sd_size Size of received SoftDevice in bytes.
+ */
+static bool softdevice_info_ok(uint32_t sd_start_addr, uint32_t sd_size)
+{
+ bool result = true;
+
+ if (SD_MAGIC_NUMBER_GET(sd_start_addr) != SD_MAGIC_NUMBER)
+ {
+ NRF_LOG_ERROR("The SoftDevice does not contain the magic number identifying it as a SoftDevice.");
+ result = false;
+ }
+ else if (SD_SIZE_GET(sd_start_addr) < ALIGN_TO_PAGE(sd_size + MBR_SIZE))
+ {
+ // The size in the info struct should be rounded up to a page boundary
+ // and be larger than the actual size + the size of the MBR.
+ NRF_LOG_ERROR("The SoftDevice size in the info struct is too small compared with the size reported in the init command.");
+ result = false;
+ }
+
+ return result;
+}
+
+
+static void postvalidate_app(dfu_init_command_t * p_init)
+{
+ s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
+
+ NRF_LOG_DEBUG("Invalidating old application in bank 0.");
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
+
+ if (!DFU_REQUIRES_SOFTDEVICE && !update_requires_softdevice(p_init))
+ {
+ // App does not need SD, so it should be placed where SD is.
+ nrf_dfu_softdevice_invalidate();
+ }
+
+ if (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
+ {
+ s_dfu_settings.app_version = p_init->fw_version;
+ }
+}
+
+
+// Function to check a received SoftDevice and/or Bootloader firmware
+// before it is copied into place.
+static bool postvalidate_sd_bl(dfu_init_command_t * p_init,
+ bool with_sd,
+ bool with_bl,
+ uint32_t start_addr)
+{
+ if (with_sd)
+ {
+ if (!softdevice_info_ok(start_addr, p_init->sd_size))
+ {
+ return false;
+ }
+
+ if (is_major_softdevice_update(start_addr))
+ {
+ NRF_LOG_WARNING("Invalidating app because it is incompatible with the SoftDevice.");
+ if (DFU_REQUIRES_SOFTDEVICE && !with_bl)
+ {
+ NRF_LOG_ERROR("Major SD update but no BL. Abort to avoid incapacitating the BL.");
+ return false;
+ }
+
+ // Invalidate app since it may not be compatible with new SD.
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
+ }
+
+ // Mark the update as valid.
+ s_dfu_settings.bank_1.bank_code = with_bl ? NRF_DFU_BANK_VALID_SD_BL
+ : NRF_DFU_BANK_VALID_SD;
+
+ s_dfu_settings.sd_size = p_init->sd_size;
+ }
+ else
+ {
+ s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_BL;
+ }
+
+
+ if (with_bl &&
+ (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false))))
+ {
+ // If the update contains a bootloader, update the version.
+ // Unless the update is a debug packet.
+ s_dfu_settings.bootloader_version = p_init->fw_version;
+ }
+
+ return true;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t src_addr, uint32_t data_len)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ dfu_init_command_t * p_init = m_packet.has_signed_command ? &m_packet.signed_command.command.init
+ : &m_packet.command.init;
+
+ if (!fw_hash_ok(p_init, src_addr, data_len))
+ {
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_VERIFICATION_FAILED);
+ }
+ else
+ {
+ if (p_init->type == DFU_FW_TYPE_APPLICATION)
+ {
+ postvalidate_app(p_init);
+ }
+ else
+ {
+ bool with_sd = p_init->type & DFU_FW_TYPE_SOFTDEVICE;
+ bool with_bl = p_init->type & DFU_FW_TYPE_BOOTLOADER;
+
+ if (!postvalidate_sd_bl(p_init, with_sd, with_bl, src_addr))
+ {
+ ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ if (with_sd && !DFU_REQUIRES_SOFTDEVICE &&
+ (src_addr == nrf_dfu_softdevice_start_address()))
+ {
+ nrf_dfu_softdevice_invalidate();
+ }
+ }
+ }
+ }
+
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ // Store CRC32 for image
+ s_dfu_settings.bank_1.image_crc = s_dfu_settings.progress.firmware_image_crc;
+ s_dfu_settings.bank_1.image_size = data_len;
+ }
+ else
+ {
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
+ }
+
+ // Set the progress to zero and remove the last command
+ memset(&s_dfu_settings.progress, 0, sizeof(dfu_progress_t));
+ memset(s_dfu_settings.init_command, 0xFF, DFU_SIGNED_COMMAND_SIZE);
+
+ s_dfu_settings.write_offset = 0;
+ s_dfu_settings.progress.update_start_address = src_addr;
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h
new file mode 100644
index 0000000..d0de004
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_validation Validation
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef __NRF_DFU_VALIDATION_H
+#define __NRF_DFU_VALIDATION_H
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "nrf_dfu_handling_error.h"
+
+/**
+ * @brief Function for module initialization.
+ *
+ * Function checks if there is a valid init packet in DFU settings written in flash.
+ */
+void nrf_dfu_validation_init(void);
+
+/**
+ * @brief Function called on reception of init command creation request.
+ *
+ * @param[in] size Size of incoming init packet.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size);
+
+/**
+ * @brief Function called on reception of fragment of init command.
+ *
+ * @param[in] p_data Init command fragment.
+ * @param[in] length Init command fragment size.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length);
+
+/**
+ * @brief Function for getting init command status.
+ *
+ * @param[out] p_offset Current offset.
+ * @param[out] p_crc Current CRC.
+ * @param[out] p_max_size Maximum size of init command.
+ */
+void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
+ uint32_t * p_crc,
+ uint32_t * p_max_size);
+
+/**
+ * @brief Function for inquiring whether a valid init command has been received.
+ *
+ * @return true if there is a valid init command. This can be true at boot time
+ * if the device was reset during a DFU operation.
+ */
+bool nrf_dfu_validation_init_cmd_present(void);
+
+/**
+ * @brief Function for validating init command.
+ *
+ * If init command is successfully validated Bank 1 details are written to out parameters.
+ *
+ * Until @ref nrf_dfu_validation_init_cmd_create is called, this function can be called
+ * again after the first time without side effects to retrieve address and length.
+ *
+ * @param[out] p_dst_data_addr Bank 1 start address if validation is successful.
+ * @param[out] p_data_len Bank 1 length if validation is successful.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
+ uint32_t * p_data_len);
+
+/**
+ * @brief Function for postvalidating the update. Function is called once all data is received.
+ *
+ * @param[in] dst_data_addr Bank 1 start address.
+ * @param[in] data_len Bank 1 length.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t dst_data_addr, uint32_t data_len);
+
+#endif //__NRF_DFU_VALIDATION_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c
new file mode 100644
index 0000000..4958dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "dfu-cc.pb.h"
+#include "nrf_dfu_ver_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_ver_validation
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#ifndef NRF_DFU_DEBUG
+#ifdef NRF_DFU_DEBUG_VERSION
+#define NRF_DFU_DEBUG 1
+#else
+#define NRF_DFU_DEBUG 0
+#endif
+#endif
+
+/** @brief Macro for reading the Firmware ID of a SoftDevice at a given base address.
+ */
+#ifndef _SD_FWID_GET
+#define _SD_FWID_GET(baseaddr) SD_OFFSET_GET_UINT16(baseaddr, 0x0C)
+#endif
+
+#define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
+
+static bool sd_req_check(uint32_t const * p_sd_req, uint8_t sd_req_cnt)
+{
+ bool result = false;
+ for (uint8_t i = 0; i < sd_req_cnt; i++)
+ {
+ if (p_sd_req[i] == _SD_FWID_GET(MBR_SIZE))
+ {
+ // Found a matching sd_req field. sd_req is ok.
+ result = true;
+ break;
+ }
+ }
+ return result;
+}
+
+static bool sd_req_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+ bool result;
+#ifdef BLE_STACK_SUPPORT_REQD
+ // The bootloader needs the SoftDevice, so disabling NRF_DFU_APP_DOWNGRADE_PREVENTION
+ // should not be applied to SoftDevice updates.
+ const bool prevent_downgrade = NRF_DFU_APP_DOWNGRADE_PREVENTION || (p_init->type == DFU_FW_TYPE_SOFTDEVICE);
+#else
+ const bool prevent_downgrade = NRF_DFU_APP_DOWNGRADE_PREVENTION;
+#endif
+
+ if (SD_PRESENT)
+ {
+ if (p_init->sd_req_count && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD))
+ {
+ result = sd_req_check(p_init->sd_req, p_init->sd_req_count);
+ }
+ else if (p_init->type == DFU_FW_TYPE_APPLICATION)
+ {
+ // The application wants to overwrite the SoftDevice.
+ if (prevent_downgrade && (p_init->sd_req_count > 1) && (p_init->sd_req[0] == SD_REQ_APP_OVERWRITES_SD))
+ {
+ // The application can overwrite the SD if sd_req[0] == 0 and table has the fwid of the current SD.
+ result = sd_req_check(p_init->sd_req, p_init->sd_req_count);
+ }
+ else
+ {
+ result = true;
+ }
+ }
+ else
+ {
+ // Don't allow SoftDevice updates which assume no SD is present already.
+ result = !prevent_downgrade || (p_init->type != DFU_FW_TYPE_SOFTDEVICE);
+ }
+ }
+ else
+ {
+ if (p_init->sd_req_count && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD))
+ {
+ // Fail if there is no SD and the update requires SD.
+ result = false;
+ }
+ else
+ {
+ // If there is no SD and update has SD it is accepted only if it has a fw_version.
+ result = !prevent_downgrade || p_init->has_fw_version;
+ }
+ }
+ return result;
+}
+
+static bool fw_hash_type_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+
+ return (p_init->hash.hash_type == DFU_HASH_TYPE_SHA256);
+}
+
+static bool fw_version_required(dfu_fw_type_t new_fw_type)
+{
+ bool result = true;
+
+ if (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)
+ {
+ result = false; // fw_version is optional in SoftDevice updates. If present, it will be checked against the app version.
+ }
+ else if (new_fw_type == DFU_FW_TYPE_APPLICATION)
+ {
+ result = NRF_DFU_APP_DOWNGRADE_PREVENTION; // fw_version is configurable in app updates.
+ }
+
+ return result;
+}
+
+
+static bool fw_type_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+
+ return ((p_init->has_type)
+ && ( (p_init->type == DFU_FW_TYPE_APPLICATION)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE)
+ || (p_init->type == DFU_FW_TYPE_BOOTLOADER)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER)));
+}
+
+
+// This function assumes p_init->has_fw_version.
+static bool fw_version_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+ ASSERT(p_init->has_fw_version);
+
+ if ( (p_init->type == DFU_FW_TYPE_APPLICATION)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE))
+ {
+ return ((p_init->fw_version >= s_dfu_settings.app_version) || !NRF_DFU_APP_DOWNGRADE_PREVENTION);
+ }
+ else
+ {
+ return (p_init->fw_version > s_dfu_settings.bootloader_version);
+ }
+}
+
+nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if (!fw_type_ok(p_init))
+ {
+ NRF_LOG_ERROR("Invalid firmware type.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ else if (!fw_hash_type_ok(p_init))
+ {
+ NRF_LOG_ERROR("Invalid hash type.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE);
+ }
+ else if (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && ((p_init->has_is_debug == false) || (p_init->is_debug == false))))
+ {
+ if (p_init->has_hw_version == false)
+ {
+ NRF_LOG_ERROR("No HW version.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ else if (p_init->hw_version != NRF_DFU_HW_VERSION)
+ {
+ NRF_LOG_WARNING("Faulty HW version.");
+ ret_val = EXT_ERR( NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE);
+ }
+ else if (!sd_req_ok(p_init))
+ {
+ NRF_LOG_WARNING("SD req not met.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE);
+ }
+ else if (p_init->has_fw_version)
+ {
+ if (!fw_version_ok(p_init))
+ {
+ NRF_LOG_WARNING("FW version too low.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE);
+ }
+ }
+ else
+ {
+ if (fw_version_required(p_init->type))
+ {
+ NRF_LOG_ERROR("FW version missing.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ }
+ }
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h
new file mode 100644
index 0000000..5014b15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __NRF_DFU_VER_VALIDATION_H
+#define __NRF_DFU_VER_VALIDATION_H
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "nrf_dfu_handling_error.h"
+#include "dfu-cc.pb.h"
+
+/** @brief SD_REQ field value which indicates that Softdevice can be overwritten by the application. */
+#define SD_REQ_APP_OVERWRITES_SD 0
+
+/**
+ * @brief Function for validating version of new firmware.
+ *
+ * @return NRF_DFU_RES_CODE_SUCCESS if successful or error code otherwise
+ */
+nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init);
+
+#endif //__NRF_DFU_VER_VALIDATION_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c
new file mode 100644
index 0000000..3e62e47
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c
@@ -0,0 +1,394 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader.h"
+
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#include "boards.h"
+#include "sdk_config.h"
+#include "nrf_power.h"
+#include "nrf_delay.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_dfu.h"
+#include "nrf_error.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_wdt.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_bootloader_app_start.h"
+#include "nrf_bootloader_fw_activation.h"
+#include "nrf_bootloader_dfu_timers.h"
+#include "app_scheduler.h"
+#include "app_timer.h"
+
+static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
+
+#define SCHED_QUEUE_SIZE 32 /**< Maximum number of events in the scheduler queue. */
+#define SCHED_EVENT_DATA_SIZE MAX(NRF_DFU_SCHED_EVENT_DATA_SIZE, APP_TIMER_SCHED_EVENT_DATA_SIZE) /**< Maximum app_scheduler event size. */
+
+#if !(defined(NRF_BL_DFU_ENTER_METHOD_BUTTON) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_PINRESET) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_GPREGRET) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_BUTTONLESS))
+ #error Configuration file is missing flags. Update sdk_config.h.
+#endif
+
+STATIC_ASSERT((NRF_BL_DFU_INACTIVITY_TIMEOUT_MS >= 100) || (NRF_BL_DFU_INACTIVITY_TIMEOUT_MS == 0),
+ "NRF_BL_DFU_INACTIVITY_TIMEOUT_MS must be 100 ms or more, or 0 to indicate that it is disabled.");
+
+#if defined(NRF_LOG_BACKEND_FLASH_START_PAGE)
+STATIC_ASSERT(NRF_LOG_BACKEND_FLASH_START_PAGE != 0,
+ "If nrf_log flash backend is used it cannot use space after code because it would collide with settings page.");
+#endif
+
+/**@brief Weak implemenation of nrf_dfu_init
+ *
+ * @note This function will be overridden if nrf_dfu.c is
+ * compiled and linked with the project
+ */
+ #if (__LINT__ != 1)
+__WEAK uint32_t nrf_dfu_init(nrf_dfu_observer_t observer)
+{
+ NRF_LOG_DEBUG("in weak nrf_dfu_init");
+ return NRF_SUCCESS;
+}
+#endif
+
+
+/**@brief Weak implementation of nrf_dfu_init
+ *
+ * @note This function must be overridden in application if
+ * user-specific initialization is needed.
+ */
+__WEAK uint32_t nrf_dfu_init_user(void)
+{
+ NRF_LOG_DEBUG("in weak nrf_dfu_init_user");
+ return NRF_SUCCESS;
+}
+
+
+static void bootloader_reset(void)
+{
+ NRF_LOG_DEBUG("Resetting bootloader.");
+
+ NRF_LOG_FINAL_FLUSH();
+
+#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+ // To allow the buffer to be flushed by the host.
+ nrf_delay_ms(100);
+#endif
+
+ NVIC_SystemReset();
+}
+
+
+static void inactivity_timeout(void)
+{
+ NRF_LOG_INFO("Inactivity timeout.");
+ bootloader_reset();
+}
+
+
+/**@brief Function for handling DFU events.
+ */
+static void dfu_observer(nrf_dfu_evt_type_t evt_type)
+{
+ switch (evt_type)
+ {
+ case NRF_DFU_EVT_DFU_STARTED:
+ case NRF_DFU_EVT_OBJECT_RECEIVED:
+ nrf_bootloader_dfu_inactivity_timer_restart(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS, inactivity_timeout);
+ break;
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ case NRF_DFU_EVT_DFU_ABORTED:
+ bootloader_reset();
+ break;
+ default:
+ break;
+ }
+
+ if (m_user_observer)
+ {
+ m_user_observer(evt_type);
+ }
+}
+
+
+/**@brief Function for initializing the event scheduler.
+ */
+static void scheduler_init(void)
+{
+ APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
+}
+
+
+/**@brief Suspend the CPU until an interrupt occurs.
+ */
+static void wait_for_event(void)
+{
+#ifdef BLE_STACK_SUPPORT_REQD
+ (void)sd_app_evt_wait();
+#else
+ // Wait for an event.
+ __WFE();
+ // Clear the internal event register.
+ __SEV();
+ __WFE();
+#endif
+}
+
+
+/**@brief Continually sleep and process tasks whenever woken.
+ */
+static void loop_forever(void)
+{
+ while (true)
+ {
+ //feed the watchdog if enabled.
+ nrf_bootloader_wdt_feed();
+
+ app_sched_execute();
+
+ if (!NRF_LOG_PROCESS())
+ {
+ wait_for_event();
+ }
+ }
+}
+
+/**@brief Function for initializing button used to enter DFU mode.
+ */
+static void dfu_enter_button_init(void)
+{
+ nrf_gpio_cfg_sense_input(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN,
+ BUTTON_PULL,
+ NRF_GPIO_PIN_SENSE_LOW);
+}
+
+
+static bool crc_on_valid_app_required(void)
+{
+ bool ret = true;
+ if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET &&
+ (nrf_power_resetreas_get() & NRF_POWER_RESETREAS_OFF_MASK))
+ {
+ nrf_power_resetreas_clear(NRF_POWER_RESETREAS_OFF_MASK);
+ ret = false;
+ }
+ else if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 &&
+ (nrf_power_gpregret2_get() & BOOTLOADER_DFU_SKIP_CRC))
+ {
+ nrf_power_gpregret2_set(nrf_power_gpregret2_get() & ~BOOTLOADER_DFU_SKIP_CRC);
+ ret = false;
+ }
+ else
+ {
+ }
+
+ return ret;
+}
+
+
+/**@brief Function for clearing all DFU enter flags that
+ * preserve state during reset.
+ *
+ * @details This is used to make sure that each of these flags
+ * is checked only once after reset.
+ */
+static void dfu_enter_flags_clear(void)
+{
+ if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
+ (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
+ {
+ // Clear RESETPIN flag.
+ NRF_POWER->RESETREAS |= POWER_RESETREAS_RESETPIN_Msk;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
+ (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
+ {
+ // Clear DFU mark in GPREGRET register.
+ nrf_power_gpregret_set(nrf_power_gpregret_get() & ~BOOTLOADER_DFU_START);
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
+ (s_dfu_settings.enter_buttonless_dfu == 1))
+ {
+ // Clear DFU flag in flash settings.
+ s_dfu_settings.enter_buttonless_dfu = 0;
+ APP_ERROR_CHECK(nrf_dfu_settings_write(NULL));
+ }
+}
+
+
+/**@brief Function for checking whether to enter DFU mode or not.
+ */
+static bool dfu_enter_check(void)
+{
+ if (!nrf_dfu_app_is_valid(crc_on_valid_app_required()))
+ {
+ NRF_LOG_DEBUG("DFU mode because app is not valid.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
+ (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via button.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
+ (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via pin-reset.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
+ (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
+ (s_dfu_settings.enter_buttonless_dfu == 1))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via bootloader settings.");
+ return true;
+ }
+
+ return false;
+}
+
+
+ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
+{
+ NRF_LOG_DEBUG("In nrf_bootloader_init");
+
+ uint32_t ret_val;
+ nrf_bootloader_fw_activation_result_t activation_result;
+ uint32_t initial_timeout;
+ bool dfu_enter = false;
+
+ m_user_observer = observer;
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTON)
+ {
+ dfu_enter_button_init();
+ }
+
+ ret_val = nrf_dfu_settings_init(false);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Check if an update needs to be activated and activate it.
+ activation_result = nrf_bootloader_fw_activate();
+
+ switch (activation_result)
+ {
+ case ACTIVATION_NONE:
+ initial_timeout = NRF_BL_DFU_INACTIVITY_TIMEOUT_MS;
+ dfu_enter = dfu_enter_check();
+ break;
+
+ case ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE:
+ initial_timeout = NRF_BL_DFU_CONTINUATION_TIMEOUT_MS;
+ dfu_enter = true;
+ break;
+
+ case ACTIVATION_SUCCESS:
+ bootloader_reset();
+ NRF_LOG_ERROR("Should never come here: After bootloader_reset()");
+ return NRF_ERROR_INTERNAL; // Should not reach this.
+
+ case ACTIVATION_ERROR:
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+
+ if (dfu_enter)
+ {
+ nrf_bootloader_wdt_init();
+
+ scheduler_init();
+
+ // Clear all DFU stop flags.
+ dfu_enter_flags_clear();
+
+ // Call user-defined init function if implemented
+ ret_val = nrf_dfu_init_user();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_bootloader_dfu_inactivity_timer_restart(initial_timeout, inactivity_timeout);
+
+ ret_val = nrf_dfu_init(dfu_observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ NRF_LOG_DEBUG("Enter main loop");
+ loop_forever(); // This function will never return.
+ NRF_LOG_ERROR("Should never come here: After looping forever.");
+ }
+ else
+ {
+ // Erase additional data like peer data or advertisement name
+ ret_val = nrf_dfu_settings_additional_erase();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_bootloader_app_start();
+ NRF_LOG_ERROR("Should never come here: After nrf_bootloader_app_start()");
+ }
+
+ // Should not be reached.
+ return NRF_ERROR_INTERNAL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h
new file mode 100644
index 0000000..d588b02
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ *
+ * @defgroup nrf_bootloader Bootloader modules
+ * @{
+ * @ingroup app_common
+ * @brief Bootloader and DFU modules
+ *
+ * The bootloader module can be used to implement a basic bootloader that
+ * can be extended with, for example, Device Firmware Update (DFU) support
+ * or custom functionality.
+ */
+
+#ifndef NRF_BOOTLOADER_H__
+#define NRF_BOOTLOADER_H__
+
+#include <stdint.h>
+#include "nrf_dfu.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for initializing the bootloader.
+ *
+ * @details This function is the entry point of all bootloader operations.
+ * If DFU functionality is compiled in, the DFU process is initialized
+ * when running this function.
+ *
+ * @note This function does not return unless an error occurred.
+ *
+ * @retval NRF_ERROR_INTERNAL Something went wrong.
+ */
+ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c
new file mode 100644
index 0000000..b12cda0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_bootloader_app_start.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_log.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_bootloader_info.h"
+
+// Do the final stages of app_start. Protect flash and run app. See nrf_bootloader_app_start_final.c
+void nrf_bootloader_app_start_final(uint32_t start_addr);
+
+void nrf_bootloader_app_start(void)
+{
+ uint32_t start_addr = MBR_SIZE; // Always boot from end of MBR. If a SoftDevice is present, it will boot the app.
+ NRF_LOG_DEBUG("Running nrf_bootloader_app_start with address: 0x%08x", start_addr);
+ uint32_t err_code;
+
+ // Disable and clear interrupts
+ // Notice that this disables only 'external' interrupts (positive IRQn).
+ NRF_LOG_DEBUG("Disabling interrupts. NVIC->ICER[0]: 0x%x", NVIC->ICER[0]);
+
+ NVIC->ICER[0]=0xFFFFFFFF;
+ NVIC->ICPR[0]=0xFFFFFFFF;
+#if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2
+ NVIC->ICER[1]=0xFFFFFFFF;
+ NVIC->ICPR[1]=0xFFFFFFFF;
+#endif
+
+ err_code = nrf_dfu_mbr_irq_forward_address_set();
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running nrf_dfu_mbr_irq_forward_address_set()");
+ }
+
+ NRF_LOG_FLUSH();
+ nrf_bootloader_app_start_final(start_addr);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h
new file mode 100644
index 0000000..0bce18d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_app Application start
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_APP_START_H__
+#define NRF_BOOTLOADER_APP_START_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+
+/**@brief Function for using hardware to protect flash from writing and reading.
+ *
+ * @details This function will apply write/erase protection to a specific area. Read
+ * protection is optional, decided by \p read_protect. This function uses
+ * the BPROT or ACL peripheral, depending on which is available.
+ *
+ * @param[in] address The start address of the area to protect. Must be a flash page
+ * boundary.
+ * @param[in] size The size of the area to protect, in bytes. Must be a multiple
+ * of flash page size.
+ * @param[in] read_protect Whether to protect the area from reading/executing as well.
+ * This is not available on chips with the BPROT peripheral
+ * (e.g. nrf52832, nrf52810).
+ *
+ * @retval NRF_SUCCESS Flash protection applied successfully.
+ * @retval NRF_ERROR_NO_MEM No more ACL instances to use for flash protection.
+ * @retval NRF_ERROR_INVALID_PARAM Address was out of range or size was not a multiple
+ * of flash page size.
+ */
+ret_code_t nrf_bootloader_flash_protect(uint32_t address, uint32_t size, bool read_protect);
+
+/**@brief Function for starting another application (and aborting the current one).
+ *
+ * @details This function uses the provided address to swap the stack pointer and then load
+ * the address of the reset handler to be executed. It checks the current system mode
+ * (thread/handler). If in thread mode, it resets into the other application.
+ * If in handler mode, isr_abort is executed to ensure that handler mode is left correctly.
+ * It then jumps into the reset handler of the other application.
+ *
+ * @note This function assumes the SoftDevice has not previously been initialized.
+ *
+ * @note This function will never return, but issues a reset into the provided application.
+ */
+void nrf_bootloader_app_start(void);
+
+#endif // NRF_BOOTLOADER_APP_START_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c
new file mode 100644
index 0000000..a818322
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_bootloader_app_start.h"
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_dfu_types.h"
+#include "nrf_assert.h"
+#include "nrf_log.h"
+#include "sdk_config.h"
+
+
+// Enabling the NRF_BOOTLOADER_READ_PROTECT define is untested.
+// Read-protecting the bootloader requires certain functions to run from RAM.
+// In GCC and SES this is done automatically when the define is enabled. You will
+// get warnings which can be ignored.
+// In Keil you must change project settings to run the entire file from RAM.
+#ifndef NRF_BOOTLOADER_READ_PROTECT
+#define NRF_BOOTLOADER_READ_PROTECT 0
+#endif
+
+
+#define HANDLER_MODE_EXIT 0xFFFFFFF9 // When this is jumped to, the CPU will exit interrupt context
+ // (handler mode), and pop values from the stack into registers.
+ // See ARM's documentation for "Exception entry and return".
+#define EXCEPTION_STACK_WORD_COUNT 8 // The number of words popped from the stack when
+ // HANDLER_MODE_EXIT is branched to.
+
+
+/**@brief Function that sets the stack pointer and link register, and starts executing a particular address.
+ *
+ * @param[in] new_msp The new value to set in the main stack pointer.
+ * @param[in] new_lr The new value to set in the link register.
+ * @param[in] addr The address to execute.
+ */
+#if defined ( __CC_ARM )
+__ASM __STATIC_INLINE void jump_to_addr(uint32_t new_msp, uint32_t new_lr, uint32_t addr)
+{
+ MSR MSP, R0;
+ MOV LR, R1;
+ BX R2;
+}
+#else
+__STATIC_INLINE void jump_to_addr(uint32_t new_msp, uint32_t new_lr, uint32_t addr)
+{
+ __ASM volatile ("MSR MSP, %[arg]" : : [arg] "r" (new_msp));
+ __ASM volatile ("MOV LR, %[arg]" : : [arg] "r" (new_lr) : "lr");
+ __ASM volatile ("BX %[arg]" : : [arg] "r" (addr));
+}
+#endif
+
+
+/**@brief Function for booting an app as if the chip was reset.
+ *
+ * @param[in] vector_table_addr The address of the app's vector table.
+ */
+__STATIC_INLINE void app_start(uint32_t vector_table_addr)
+{
+ const uint32_t current_isr_num = (__get_IPSR() & IPSR_ISR_Msk);
+ const uint32_t new_msp = *((uint32_t *)(vector_table_addr)); // The app's Stack Pointer is found as the first word of the vector table.
+ const uint32_t reset_handler = *((uint32_t *)(vector_table_addr + sizeof(uint32_t))); // The app's Reset Handler is found as the second word of the vector table.
+ const uint32_t new_lr = 0xFFFFFFFF;
+
+ __set_CONTROL(0x00000000); // Set CONTROL to its reset value 0.
+ __set_PRIMASK(0x00000000); // Set PRIMASK to its reset value 0.
+ __set_BASEPRI(0x00000000); // Set BASEPRI to its reset value 0.
+ __set_FAULTMASK(0x00000000); // Set FAULTMASK to its reset value 0.
+
+ if (current_isr_num == 0)
+ {
+ // The CPU is in Thread mode (main context).
+ jump_to_addr(new_msp, new_lr, reset_handler); // Jump directly to the App's Reset Handler.
+ }
+ else
+ {
+ // The CPU is in Handler mode (interrupt context).
+
+ const uint32_t exception_stack[EXCEPTION_STACK_WORD_COUNT] = // To be copied onto the stack.
+ {
+ 0x00000000, // New value of R0. Cleared by setting to 0.
+ 0x00000000, // New value of R1. Cleared by setting to 0.
+ 0x00000000, // New value of R2. Cleared by setting to 0.
+ 0x00000000, // New value of R3. Cleared by setting to 0.
+ 0x00000000, // New value of R12. Cleared by setting to 0.
+ 0xFFFFFFFF, // New value of LR. Cleared by setting to all 1s.
+ reset_handler, // New value of PC. The CPU will continue by executing the App's Reset Handler.
+ xPSR_T_Msk, // New value of xPSR (Thumb mode set).
+ };
+ const uint32_t exception_sp = new_msp - sizeof(exception_stack);
+
+ memcpy((uint32_t *)exception_sp, exception_stack, sizeof(exception_stack)); // 'Push' exception_stack onto the App's stack.
+
+ jump_to_addr(exception_sp, new_lr, HANDLER_MODE_EXIT); // 'Jump' to the special value to exit handler mode. new_lr is superfluous here.
+ // exception_stack will be popped from the stack, so the resulting SP will be the new_msp.
+ // Execution will continue from the App's Reset Handler.
+ }
+}
+
+#if NRF_BOOTLOADER_READ_PROTECT
+#ifdef __ICCARM__
+__ramfunc
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+__attribute__((noinline, long_call, section(".data")))
+#elif defined ( __CC_ARM )
+#warning "Keil requires changes to project settings to run this file from RAM. Ignore this warning if configuration has been made."
+#endif
+#endif
+ret_code_t nrf_bootloader_flash_protect(uint32_t address, uint32_t size, bool read_protect)
+{
+ if ((size & (CODE_PAGE_SIZE - 1)) || (address > BOOTLOADER_SETTINGS_ADDRESS))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#if defined(ACL_PRESENT)
+
+ // Protect using ACL.
+ static uint32_t acl_instance = 0;
+
+ uint32_t const wmask = (ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos);
+ uint32_t const rwmask = wmask | (ACL_ACL_PERM_READ_Disable << ACL_ACL_PERM_READ_Pos);
+ uint32_t const mask = read_protect ? rwmask: wmask;
+
+ do
+ {
+ if (acl_instance >= ACL_REGIONS_COUNT)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ NRF_ACL->ACL[acl_instance].ADDR = address;
+ NRF_ACL->ACL[acl_instance].SIZE = size;
+ NRF_ACL->ACL[acl_instance].PERM = mask;
+
+ acl_instance++;
+
+ } while (NRF_ACL->ACL[acl_instance - 1].ADDR != address
+ || NRF_ACL->ACL[acl_instance - 1].SIZE != size
+ || NRF_ACL->ACL[acl_instance - 1].PERM != mask); // Check whether the acl_instance has been used before.
+
+#elif defined (BPROT_PRESENT)
+
+ // Protect using BPROT. BPROT does not support read protection.
+ uint32_t pagenum_start = address / CODE_PAGE_SIZE;
+ uint32_t pagenum_end = pagenum_start + ((size - 1) / CODE_PAGE_SIZE);
+
+ for (uint32_t i = pagenum_start; i <= pagenum_end; i++)
+ {
+ uint32_t config_index = i / 32;
+ uint32_t mask = (1 << (i - config_index * 32));
+
+ switch (config_index)
+ {
+ case 0:
+ NRF_BPROT->CONFIG0 = mask;
+ break;
+ case 1:
+ NRF_BPROT->CONFIG1 = mask;
+ break;
+ case 2:
+ NRF_BPROT->CONFIG2 = mask;
+ break;
+ case 3:
+ NRF_BPROT->CONFIG3 = mask;
+ break;
+ }
+ }
+
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_BOOTLOADER_READ_PROTECT
+#ifdef __ICCARM__
+__ramfunc
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+__attribute__((noinline, long_call, section(".data")))
+#elif defined ( __CC_ARM )
+#warning "Keil requires changes to project settings to run this file from RAM. Ignore this warning if configuration has been made."
+#endif
+#endif
+void nrf_bootloader_app_start_final(uint32_t vector_table_addr)
+{
+ ret_code_t ret_val;
+
+ // Protect MBR & bootloader code and params pages.
+ if (NRF_BOOTLOADER_READ_PROTECT)
+ {
+ ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, NRF_BOOTLOADER_READ_PROTECT);
+ }
+
+ // Size of the flash area to protect.
+ uint32_t area_size;
+
+ if (!NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ area_size = BOOTLOADER_SIZE + NRF_MBR_PARAMS_PAGE_SIZE;
+ }
+ else
+ {
+ area_size = BOOTLOADER_SIZE + NRF_MBR_PARAMS_PAGE_SIZE + BOOTLOADER_SETTINGS_PAGE_SIZE;
+ }
+
+ ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR,
+ area_size,
+ NRF_BOOTLOADER_READ_PROTECT);
+
+ if (!NRF_BOOTLOADER_READ_PROTECT && (ret_val != NRF_SUCCESS))
+ {
+ NRF_LOG_ERROR("Could not protect bootloader and settings pages, 0x%x.", ret_val);
+ }
+
+ // Run application
+ app_start(vector_table_addr);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c
new file mode 100644
index 0000000..a6b056e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader_dfu_timers.h"
+
+#include "app_timer.h"
+#include "nrf_clock.h"
+
+APP_TIMER_DEF(m_dfu_inactivity_timer); //!< Timer for aborting DFU if no update happens.
+APP_TIMER_DEF(m_wdt_feed_timer); //!< Timer for feeding the application's watchdog (WDT) while the bootloader is running.
+
+static bool m_app_timer_initialized;
+
+/** @brief Function for handling the timeouts by calling the callback in the context.
+ */
+static void timeout_handler(void * p_context)
+{
+ if (p_context)
+ {
+ //lint -save -e611 "Suspicious cast"
+ ((nrf_bootloader_dfu_timeout_callback_t)p_context)();
+ //lint -restore
+ }
+}
+
+
+/**@brief Initialization of app_timer. Function ensures that initialization happens only once.
+ */
+static void timer_init(void)
+{
+ if (!m_app_timer_initialized)
+ {
+ if (!nrf_clock_lf_is_running())
+ {
+ nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
+
+ // Wait for the clock to be ready.
+ while (!nrf_clock_lf_is_running()) {;}
+ }
+
+ uint32_t err_code = app_timer_init();
+ APP_ERROR_CHECK(err_code);
+
+ // Start a single shot timer that will reset the DFU on timeout.
+ err_code = app_timer_create(&m_dfu_inactivity_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timeout_handler);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ err_code = app_timer_create(&m_wdt_feed_timer,
+ APP_TIMER_MODE_REPEATED,
+ timeout_handler);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ m_app_timer_initialized = true;
+ }
+}
+
+
+/**@brief Function for initializing app_timer if necessary, and (re)starting a timer.
+ */
+static void timer_start(app_timer_t * p_timer, uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ ret_code_t err_code;
+
+ timer_init();
+
+ err_code = app_timer_stop(p_timer);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if (timeout_ms != 0)
+ {
+ //lint -save -e611 "Suspicious cast"
+ err_code = app_timer_start(p_timer, APP_TIMER_TICKS(timeout_ms), (void *)callback);
+ //lint -restore
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+}
+
+
+void nrf_bootloader_dfu_inactivity_timer_restart(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ timer_start(m_dfu_inactivity_timer, timeout_ms, callback);
+}
+
+
+void nrf_bootloader_wdt_feed_timer_start(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ timer_start(m_wdt_feed_timer, timeout_ms, callback);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h
new file mode 100644
index 0000000..5104dfd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_dfu_timers Timers for DFU in the bootloader
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_DFU_TIMERS_H__
+#define NRF_BOOTLOADER_DFU_TIMERS_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**@brief Handler called on timeout of a timer requested by the watchdog.
+ */
+typedef void (*nrf_bootloader_dfu_timeout_callback_t)(void);
+
+
+/**@brief Function for restarting the inactivity timer.
+ *
+ * @note Calling this function cancels any previous calls to this function.
+ *
+ * @param[in] timeout_ms The number of milliseconds until reset if not restarted.
+ * If 0 is passed, the timer will be stopped and not restarted.
+ * @param[in] callback Function to be called on timeout.
+ */
+void nrf_bootloader_dfu_inactivity_timer_restart(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback);
+
+
+/**@brief Function for initializing and starting a repeated timer for feeding the watchdog.
+ *
+ * @param[in] timeout_ms Timer period.
+ * @param[in] callback Function called on every timeout.
+ */
+void nrf_bootloader_wdt_feed_timer_start(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_DFU_TIMERS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c
new file mode 100644
index 0000000..40e4870
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c
@@ -0,0 +1,436 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_bootloader_fw_activation.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_bootloader_info.h"
+#include "crc32.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_wdt.h"
+
+
+static volatile bool m_flash_write_done;
+
+
+/**
+ * @brief Function for copying image. Image is copied in chunks. Frequency of storing progress
+ * in flash is configured by input parameter.
+ *
+ * @param[in] dst_addr Destination address. Must be page aligned.
+ * @param[in] src_addr Source address. Must be higher value than dst_addr.
+ * @param[in] size Image size.
+ * @param[in] progress_update_step Number of copied pages that triggers saving progress to non-volatile memory.
+ * Note that step can be decreased if there is a risk of corruption caused by source
+ * and destination overlapping.
+ *
+ * @return NRF_SUCCESS or error code in case of failure.
+ */
+static uint32_t image_copy(uint32_t dst_addr,
+ uint32_t src_addr,
+ uint32_t size,
+ uint32_t progress_update_step)
+{
+ if (src_addr == dst_addr)
+ {
+ NRF_LOG_DEBUG("No copy needed src_addr: 0x%x, dst_addr: 0x%x", src_addr, dst_addr);
+ return NRF_SUCCESS;
+ }
+
+ ASSERT(src_addr >= dst_addr);
+ ASSERT(progress_update_step > 0);
+ ASSERT((dst_addr % CODE_PAGE_SIZE) == 0);
+
+ uint32_t max_safe_progress_upd_step = (src_addr - dst_addr)/CODE_PAGE_SIZE;
+ ASSERT(max_safe_progress_upd_step > 0);
+
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t pages_left = CEIL_DIV(size, CODE_PAGE_SIZE);
+
+ //Firmware copying is time consuming operation thus watchdog handling is started
+ nrf_bootloader_wdt_init();
+
+ progress_update_step = MIN(progress_update_step, max_safe_progress_upd_step);
+
+ while (size > 0)
+ {
+ uint32_t pages;
+ uint32_t bytes;
+ if (pages_left <= progress_update_step)
+ {
+ pages = pages_left;
+ bytes = size;
+ }
+ else
+ {
+ pages = progress_update_step;
+ bytes = progress_update_step * CODE_PAGE_SIZE;
+ }
+ // Erase the target pages
+ ret_val = nrf_dfu_flash_erase(dst_addr, pages, NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ // Flash one page
+ NRF_LOG_DEBUG("Copying 0x%x to 0x%x, size: 0x%x", src_addr, dst_addr, bytes);
+ ret_val = nrf_dfu_flash_store(dst_addr,
+ (uint32_t *)src_addr,
+ ALIGN_NUM(sizeof(uint32_t), bytes),
+ NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ pages_left -= pages;
+ size -= bytes;
+ dst_addr += bytes;
+ src_addr += bytes;
+ s_dfu_settings.write_offset += bytes;
+
+ //store progress in flash on every successful chunk write
+ ret_val = nrf_dfu_settings_write(NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to write image copying progress to settings page.");
+ return ret_val;
+ }
+ }
+
+ return ret_val;
+}
+
+/** @brief Function to continue application update.
+ *
+ * @details This function will be called after reset if there is a valid application in Bank1
+ * required to be copied down to Bank 0.
+ *
+ * @return NRF_SUCCESS if continuation was successful, NRF_ERROR_INTERNAL if new firmware does not
+ * contain softdevice or other error coming from modules used by this function.
+ */
+static uint32_t app_activate(void)
+{
+ // This function is only in use when new app is present in Bank 1
+ uint32_t const image_size = s_dfu_settings.bank_1.image_size;
+
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t target_addr = nrf_dfu_bank0_start_addr() + s_dfu_settings.write_offset;
+ uint32_t length_left = (image_size - s_dfu_settings.write_offset);
+ uint32_t crc;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_app_continue");
+
+ src_addr += s_dfu_settings.write_offset;
+
+ if (src_addr == target_addr)
+ {
+ length_left = 0;
+ }
+
+ ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to copy firmware.");
+ return ret_val;
+ }
+
+ // Check the CRC of the copied data. Enable if so.
+ crc = crc32_compute((uint8_t*)nrf_dfu_bank0_start_addr(), image_size, NULL);
+
+ if (crc == s_dfu_settings.bank_1.image_crc)
+ {
+ NRF_LOG_DEBUG("Setting app as valid");
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
+ s_dfu_settings.bank_0.image_crc = crc;
+ s_dfu_settings.bank_0.image_size = image_size;
+ }
+ else
+ {
+ NRF_LOG_ERROR("CRC computation failed for copied app: "
+ "src crc: 0x%08x, res crc: 0x%08x",
+ s_dfu_settings.bank_1.image_crc,
+ crc);
+ }
+
+ return ret_val;
+}
+
+
+/** @brief Function to execute the continuation of a SoftDevice update.
+ *
+ * @return NRF_SUCCESS if continuation was successful, NRF_ERROR_INTERNAL if new firmware does not
+ * contain softdevice or other error coming from modules used by this function.
+ */
+static uint32_t sd_activate(void)
+{
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t target_addr = nrf_dfu_softdevice_start_address() + s_dfu_settings.write_offset;
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+ uint32_t sd_size = s_dfu_settings.sd_size;
+ uint32_t length_left = ALIGN_TO_PAGE(sd_size - s_dfu_settings.write_offset);
+
+ NRF_LOG_DEBUG("Enter nrf_bootloader_dfu_sd_continue");
+
+ if (SD_MAGIC_NUMBER_GET(src_addr) != SD_MAGIC_NUMBER)
+ {
+ NRF_LOG_ERROR("Source address does not contain a valid SoftDevice.")
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // This can be a continuation due to a power failure
+ src_addr += s_dfu_settings.write_offset;
+
+ if (s_dfu_settings.write_offset == sd_size)
+ {
+ NRF_LOG_DEBUG("SD already copied");
+ return NRF_SUCCESS;
+ }
+
+ if (s_dfu_settings.write_offset == 0)
+ {
+ NRF_LOG_DEBUG("Updating SD. Old SD ver: %d, New ver: %d",
+ SD_VERSION_GET(MBR_SIZE) / 1000000, SD_VERSION_GET(src_addr) / 1000000);
+ }
+
+ ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to copy firmware.");
+ return ret_val;
+ }
+
+ ret_val = nrf_dfu_settings_write(NULL);
+
+ return ret_val;
+}
+
+
+/** @brief Function to continue bootloader update.
+ *
+ * @details This function will be called after reset if there is a valid bootloader in Bank 0 or Bank 1
+ * required to be relocated and activated through MBR commands.
+ *
+ * @return This function will not return if the bootloader is copied successfully.
+ * After the copy is verified, the device will reset and start the new bootloader.
+ *
+ * @retval NRF_SUCCESS Continuation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH Invalid length of flash operation.
+ * @retval NRF_ERROR_NO_MEM If no parameter page is provided (see sds for more info).
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid command is given.
+ * @retval NRF_ERROR_INTERNAL Internal error that should not happen.
+ * @retval NRF_ERROR_FORBIDDEN If NRF_UICR->BOOTADDR is not set.
+ */
+static uint32_t bl_activate(void)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_DATA;
+ nrf_dfu_bank_t * p_bank = &s_dfu_settings.bank_1;
+ uint32_t len = p_bank->image_size;
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+
+ if (p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL)
+ {
+ src_addr += s_dfu_settings.sd_size;
+ len -= s_dfu_settings.sd_size;
+ }
+
+ NRF_LOG_DEBUG("Verifying BL: Addr: 0x%08x, Src: 0x%08x, Len: 0x%08x", BOOTLOADER_START_ADDR, src_addr, len);
+
+ // This code is a configurable workaround for updating SD+BL from SDK 12.x.y - 14.1.0
+ // SoftDevice size increase would lead to unaligned source address when comparing new BL in SD+BL updates.
+ // This workaround is not required once BL is successfully installed with a version that is compiled SDK 14.1.0
+#if defined(NRF52832_XXAA) && defined(BLE_STACK_SUPPORT_REQD)
+ if ((p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL) &&
+ (memcmp((void *)BOOTLOADER_START_ADDR, (void *)(src_addr - 0x4000), len) == 0))
+ {
+ ret_val = NRF_SUCCESS;
+ }
+#endif // defined(NRF52832_XXAA)
+
+ // Check if the BL has already been copied.
+ if ((ret_val != NRF_SUCCESS) &&
+ (memcmp((void *)BOOTLOADER_START_ADDR, (void *)src_addr, len) == 0))
+ {
+ ret_val = NRF_SUCCESS;
+ }
+
+ // If the bootloader is the same as the banked version, the copy is finished
+ if (ret_val == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("No bootloader copy needed, bootloader update complete.");
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Copying bootloader: Src: 0x%08x, Len: 0x%08x", src_addr, len);
+ NRF_LOG_FLUSH();
+
+ nrf_bootloader_wdt_feed();
+
+ // Bootloader is different than the banked version. Continue copy
+ // Note that if the SD and BL was combined, then the split point between them is in s_dfu_settings.sd_size
+ // On success this function won't return.
+ ret_val = nrf_dfu_mbr_copy_bl((uint32_t*)src_addr, len);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Request to copy BL failed");
+ }
+ }
+
+ return ret_val;
+}
+
+
+/** @brief Function to continue combined bootloader and SoftDevice update.
+ *
+ * @details This function will be called after reset if there is a valid bootloader and SoftDevice in Bank 0 or Bank 1
+ * required to be relocated and activated through MBR commands.
+ *
+ * @retval NRF_SUCCESS Continuation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH Invalid length.
+ * @retval NRF_ERROR_NO_MEM If UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid command is given.
+ * @retval NRF_ERROR_INTERNAL Indicates that the contents of the memory blocks where not verified correctly after copying.
+ * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying.
+ * @retval NRF_ERROR_FORBIDDEN If NRF_UICR->BOOTADDR is not set.
+ */
+static uint32_t sd_bl_activate()
+{
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_sd_bl_continue");
+
+ ret_val = sd_activate();
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("SD+BL: SD copy failed");
+ return ret_val;
+ }
+
+ ret_val = bl_activate();
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("SD+BL: BL copy failed");
+ return ret_val;
+ }
+
+ return ret_val;
+}
+
+
+static void flash_write_callback(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ m_flash_write_done = true;
+}
+
+
+nrf_bootloader_fw_activation_result_t nrf_bootloader_fw_activate(void)
+{
+ nrf_bootloader_fw_activation_result_t result;
+ uint32_t ret_val = NRF_SUCCESS;
+ nrf_dfu_bank_t * p_bank = &s_dfu_settings.bank_1;
+ bool sd_update = false;
+
+
+ NRF_LOG_DEBUG("Enter nrf_bootloader_fw_activate");
+
+ switch (p_bank->bank_code)
+ {
+ case NRF_DFU_BANK_VALID_APP:
+ NRF_LOG_DEBUG("Valid App");
+ ret_val = app_activate();
+ break;
+ case NRF_DFU_BANK_VALID_SD:
+ NRF_LOG_DEBUG("Valid SD");
+ ret_val = sd_activate();
+ sd_update = true;
+ break;
+ case NRF_DFU_BANK_VALID_BL:
+ NRF_LOG_DEBUG("Valid BL");
+ ret_val = bl_activate();
+ break;
+ case NRF_DFU_BANK_VALID_SD_BL:
+ NRF_LOG_DEBUG("Valid SD + BL");
+ ret_val = sd_bl_activate();
+ sd_update = true;
+ break;
+ case NRF_DFU_BANK_INVALID:
+ default:
+ NRF_LOG_INFO("No firmware to activate.");
+ return ACTIVATION_NONE;
+ }
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Activation failed with error %d (bank code: 0x%x)", ret_val, p_bank->bank_code);
+ result = ACTIVATION_ERROR;
+ }
+
+ // Invalidate bank, marking completion.
+ nrf_dfu_bank_invalidate(p_bank);
+
+ m_flash_write_done = false;
+ ret_val = nrf_dfu_settings_write(flash_write_callback);
+ ASSERT(m_flash_write_done);
+
+ /* At this point flash module is performing blocking operation. It is expected that operation is already performed. */
+ if (ret_val == NRF_SUCCESS)
+ {
+ result = ACTIVATION_SUCCESS;
+ if (sd_update && nrf_dfu_app_is_valid(true))
+ {
+ //If SD was updated and application is valid we want to stay in DFU to receive application.
+ NRF_LOG_DEBUG("A SoftDevice has just been activated. It's likely that an application will come immediately");
+ result = ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE;
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Could not write settings.");
+ result = ACTIVATION_ERROR;
+ }
+
+ return result;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h
new file mode 100644
index 0000000..312491d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_fw_activation Firmware activation
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_FW_ACTIVATION_H__
+#define NRF_BOOTLOADER_FW_ACTIVATION_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ ACTIVATION_NONE, //!< No new update was found.
+ ACTIVATION_SUCCESS, //!< Update was successfully activated.
+ ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE, //!< Update was successfully activated, but there might be additional update(s) to be transferred.
+ ACTIVATION_ERROR, //!< Activation of an update failed.
+} nrf_bootloader_fw_activation_result_t;
+
+/** @brief Function for activating a firmware received during DFU.
+ *
+ * @details This function initiates or continues the DFU copy-back
+ * routines. These routines are fail-safe operations to activate
+ * either a new SoftDevice, bootloader, combination of SoftDevice and
+ * bootloader, or a new application.
+ *
+ * @details This function relies on accessing MBR commands through supervisor calls.
+ * It does not rely on the SoftDevice for flash operations.
+ *
+ * @note When updating the bootloader or both bootloader and SoftDevice in combination,
+ * this function does not return, but rather initiates a reboot to activate
+ * the new bootloader.
+ *
+ * @retval ACTIVATION_NONE If no update was found.
+ * @retval ACTIVATION_SUCCESS If the firmware update was successfully activated.
+ * @retval ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE If the firmware update was successfully activated,
+ * but there are likely more updates to be transferred.
+ * @retval ACTIVATION_ERROR If the firmware update could not be activated.
+ */
+nrf_bootloader_fw_activation_result_t nrf_bootloader_fw_activate(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_FW_ACTIVATION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c
new file mode 100644
index 0000000..77a8ad1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader_info.h"
+
+
+/** @brief This variable ensures that the linker script will write the bootloader start address
+ * to the UICR register. This value will be written in the HEX file and thus written to
+ * UICR when the bootloader is flashed into the chip.
+ */
+#if defined (__CC_ARM )
+ #pragma push
+ #pragma diag_suppress 1296
+ uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS)))
+ = BOOTLOADER_START_ADDR;
+ #pragma pop
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+ volatile uint32_t m_uicr_bootloader_start_address __attribute__ ((section(".uicr_bootloader_start_address")))
+ = BOOTLOADER_START_ADDR;
+#elif defined ( __ICCARM__ )
+ __root const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOTLOADER_START_ADDRESS
+ = BOOTLOADER_START_ADDR;
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h
new file mode 100644
index 0000000..812cddb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_info Bootloader Information
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_INFO_H__
+#define NRF_BOOTLOADER_INFO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "app_util.h"
+#include "nrf.h"
+#include "nrf_mbr.h"
+
+/** @brief Macro for getting the start address of the bootloader image.
+ *
+ * The macro is not a compile time symbol. It cannot be used as a
+ * constant expression, for example, inside a static assert or linker script
+ * at-placement.
+ */
+#ifndef BOOTLOADER_START_ADDR
+#if (__LINT__ == 1)
+ #define BOOTLOADER_START_ADDR (0x3AC00)
+#elif defined(CODE_START)
+ #define BOOTLOADER_START_ADDR (CODE_START)
+#else
+ #error Not a valid compiler/linker for BOOTLOADER_START_ADDR.
+#endif
+#endif
+
+
+/** @brief Macro for getting the size of the bootloader image.
+ */
+#ifndef BOOTLOADER_SIZE
+#if defined ( NRF51 )
+ #define BOOTLOADER_SIZE (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_START_ADDR)
+#elif defined( NRF52_SERIES )
+ #define BOOTLOADER_SIZE (NRF_MBR_PARAMS_PAGE_ADDRESS - BOOTLOADER_START_ADDR)
+#elif (__LINT__ == 1)
+ #define BOOTLOADER_SIZE (0x6000)
+#endif
+#endif
+
+
+/**
+ * @brief Bootloader start address in UICR.
+ *
+ * Register location in UICR where the bootloader start address is stored.
+ *
+ * @note If the value at the given location is 0xFFFFFFFF, the bootloader address is not set.
+ */
+#define NRF_UICR_BOOTLOADER_START_ADDRESS (NRF_UICR_BASE + 0x14)
+
+
+// The following macros are for accessing the SoftDevice information structure,
+// which is found inside the SoftDevice binary.
+
+/** @brief Macro for converting an offset inside the SoftDevice information struct to an absolute address.
+ */
+#define SD_INFO_ABS_OFFSET_GET(baseaddr, offset) ((baseaddr) + (SOFTDEVICE_INFO_STRUCT_OFFSET) + (offset))
+
+/** @brief Macros for reading a byte or a word at a particular offset inside a SoftDevice information struct.
+ * Use MBR_SIZE as baseaddr when the SoftDevice is installed just above the MBR (the usual case).
+ */
+#define SD_OFFSET_GET_UINT32(baseaddr, offset) (*((uint32_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+#define SD_OFFSET_GET_UINT16(baseaddr, offset) (*((uint16_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+#define SD_OFFSET_GET_UINT8(baseaddr, offset) (*((uint8_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "nrf_sdm.h"
+#else
+/** @brief The offset inside the SoftDevice at which the information struct is placed.
+ * To see the layout of the information struct, see the SoftDevice specification.
+ */
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+#define SD_INFO_STRUCT_SIZE(baseaddr) SD_OFFSET_GET_UINT8(baseaddr, 0x00)
+
+/** @brief Macro for reading the size of a SoftDevice at a given base address.
+ */
+#ifndef SD_SIZE_GET
+#define SD_SIZE_GET(baseaddr) SD_OFFSET_GET_UINT32(baseaddr, 0x08)
+#endif
+
+/** @brief Macro for reading the version of a SoftDevice at a given base address.
+ * This expression checks the length of the information struct to see if the version is present.
+ * The version number is constructed like this:
+ * major_version * 1000000 + minor_version * 1000 + bugfix_version
+ */
+#ifndef SD_VERSION_GET
+#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE(baseaddr) > (0x14)) \
+ ? SD_OFFSET_GET_UINT32(baseaddr, 0x14) \
+ : 0)
+#endif
+#endif
+
+
+/** @brief Macro for reading the magic number of a SoftDevice at a given base address.
+ */
+#ifndef SD_MAGIC_NUMBER_GET
+#define SD_MAGIC_NUMBER_GET(baseaddr) SD_OFFSET_GET_UINT32(baseaddr, 0x04)
+#endif
+
+/** @brief Macro for getting the absolute address of the magic number.
+ */
+#define SD_MAGIC_NUMBER_ABS_OFFSET_GET(baseaddr) SD_INFO_ABS_OFFSET_GET(baseaddr, 0x04)
+
+/** @brief The number present at a specific location in all SoftDevices.
+ */
+#define SD_MAGIC_NUMBER ((uint32_t)0x51B1E5DB)
+
+/** @brief Whether a SoftDevice is at its regular location.
+ */
+#ifndef SD_PRESENT
+#define SD_PRESENT ((SD_MAGIC_NUMBER_GET(MBR_SIZE)) == (SD_MAGIC_NUMBER))
+#endif
+
+/** @brief The multiplier for the major version of the SoftDevice. See \ref SD_VERSION_GET
+ */
+#define SD_MAJOR_VERSION_MULTIPLIER (1000000)
+
+/** @brief Read the major version of the SoftDevice from the raw version number. See \ref SD_VERSION_GET.
+ */
+#define SD_MAJOR_VERSION_EXTRACT(raw_version) ((raw_version)/SD_MAJOR_VERSION_MULTIPLIER)
+
+
+#define BOOTLOADER_DFU_GPREGRET_MASK (0xB0) /**< Magic pattern written to GPREGRET register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
+#define BOOTLOADER_DFU_START_BIT_MASK (0x01) /**< Bit mask to signal from main application to enter DFU mode using a buttonless service. */
+
+#define BOOTLOADER_DFU_GPREGRET2_MASK (0xA8) /**< Magic pattern written to GPREGRET2 register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
+#define BOOTLOADER_DFU_SKIP_CRC_BIT_MASK (0x01) /**< Bit mask to signal from main application that CRC-check is not needed for image verification. */
+
+
+#define BOOTLOADER_DFU_START (BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK) /**< Magic number to signal that bootloader should enter DFU mode because of signal from Buttonless DFU in main app.*/
+#define BOOTLOADER_DFU_SKIP_CRC (BOOTLOADER_DFU_GPREGRET2_MASK | BOOTLOADER_DFU_SKIP_CRC_BIT_MASK) /**< Magic number to signal that CRC can be skipped due to low power modes.*/
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef NRF_BOOTLOADER_INFO_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c
new file mode 100644
index 0000000..b75d6ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader_wdt.h"
+#include "nrf_wdt.h"
+#include "nrf_bootloader_dfu_timers.h"
+#include "nrf_log_ctrl.h"
+
+#define NRF_LOG_MODULE_NAME nrf_bootloader_wdt
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+//Flag used to determine if internal feeding should stay active.
+static bool m_wdt_keep_internal_feed;
+
+static void wdt_feed(void)
+{
+ if (nrf_wdt_started())
+ {
+ for (nrf_wdt_rr_register_t i = NRF_WDT_RR0; i < NRF_WDT_RR7; i++)
+ {
+ if (nrf_wdt_reload_request_is_enabled(i))
+ {
+ nrf_wdt_reload_request_set(i);
+ }
+ }
+ }
+}
+
+
+static void wdt_feed_timer_handler(void)
+{
+ if (m_wdt_keep_internal_feed)
+ {
+ NRF_LOG_INFO("Internal feed");
+ wdt_feed();
+ }
+}
+
+
+void WDT_IRQHandler(void)
+{
+ nrf_wdt_event_clear(NRF_WDT_EVENT_TIMEOUT);
+ NRF_LOG_FINAL_FLUSH();
+}
+
+void nrf_bootloader_wdt_init(void)
+{
+ static bool initialized = false;
+
+ if (initialized)
+ {
+ return;
+ }
+
+ if (nrf_wdt_started())
+ {
+ uint32_t approx_wdt_ms = nrf_wdt_reload_value_get() / 32;
+
+ NRF_LOG_INFO("WDT enabled CRV:%d ms", approx_wdt_ms);
+
+ //wdt_ticks must be reduced (0.75) to feed the watchdog before the timeout.
+ uint32_t reduced_timeout_ms = (approx_wdt_ms * 3)/4;
+
+ /* Ideally, watchdog should be fed by the bootloader from the main context but if bootloader latency
+ * (mainly driven by signature check) is big enough there is a risk that watchdog will not be fed
+ * on time. In that case watchdog will be fed from timer context. */
+ m_wdt_keep_internal_feed =
+ (reduced_timeout_ms < NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS);
+
+ /* initial watchdog feed */
+ wdt_feed();
+
+ /* If internal feed is needed or WDT is active in sleep module must provide regular wakeup interrupt.*/
+ bool wdt_start_timer = m_wdt_keep_internal_feed || (NRF_WDT->CONFIG & WDT_CONFIG_SLEEP_Msk);
+ if (wdt_start_timer)
+ {
+ NRF_LOG_INFO("Starting a timer (%d ms) for feeding watchdog.", reduced_timeout_ms);
+ nrf_bootloader_wdt_feed_timer_start(reduced_timeout_ms, wdt_feed_timer_handler);
+ }
+
+ NVIC_EnableIRQ(WDT_IRQn);
+ }
+ else
+ {
+ NRF_LOG_INFO("WDT is not enabled");
+ }
+
+ initialized = true;
+}
+
+void nrf_bootloader_wdt_feed(void)
+{
+ if (nrf_wdt_started())
+ {
+ wdt_feed();
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h
new file mode 100644
index 0000000..0a6cb9b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BOOTLOADER_WDT_H
+#define NRF_BOOTLOADER_WDT_H
+
+/**@file
+ *
+ * @defgroup nrf_bootloader_wdt Automated feeding of the watchdog
+ * @{
+ * @ingroup nrf_bootloader
+ * @brief Module that keeps the WDT from timing out if the WDT has been started in the application.
+ */
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @brief Function for checking whether the WDT peripheral is started and for getting its configuration.
+ *
+ * The module uses app_timer to start regular feeding of the watchdog. Timer interval
+ * is chosen based on watchdog settings. When @ref nrf_bootloader_wdt_feed is called, internal
+ * feeding is stopped assuming that the application takes responsibity of watchdog feeding.
+ * However, if @ref NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS or the watchdog is configured to
+ * run during sleep, then internal feeding (from app_timer handler context) is kept active.
+ */
+void nrf_bootloader_wdt_init(void);
+
+
+/**
+ * @brief Function for feeding the watchdog (if active).
+ */
+void nrf_bootloader_wdt_feed(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif //NRF_BOOTLOADER_WDT_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
new file mode 100644
index 0000000..8e14b05
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
@@ -0,0 +1,265 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_serial.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+
+
+
+static uint32_t response_ext_err_payload_add(uint8_t * p_buffer, uint32_t buf_offset)
+{
+ p_buffer[buf_offset] = ext_error_get();
+ (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+
+ return 1;
+}
+
+
+static void response_send(nrf_dfu_serial_t * p_transport,
+ nrf_dfu_response_t const * p_response)
+{
+ uint8_t index = 0;
+ uint8_t * p_serialized_rsp = p_transport->p_rsp_buf;
+
+ NRF_LOG_DEBUG("Sending Response: [0x%01x, 0x%01x]", p_response->request, p_response->result);
+
+ p_serialized_rsp[index++] = NRF_DFU_OP_RESPONSE;
+ p_serialized_rsp[index++] = p_response->request;
+ p_serialized_rsp[index++] = (uint8_t)(p_response->result);
+
+ if (p_response->result == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ switch (p_response->request)
+ {
+ case NRF_DFU_OP_PROTOCOL_VERSION:
+ {
+ p_serialized_rsp[index] = p_response->protocol.version;
+ index += sizeof(uint8_t);
+ } break;
+
+ case NRF_DFU_OP_HARDWARE_VERSION:
+ {
+ index += uint32_encode(p_response->hardware.part, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.variant, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.rom_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.ram_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.rom_page_size, &p_serialized_rsp[index]);
+ } break;
+
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ p_serialized_rsp[index++] = p_response->firmware.type;
+ index += uint32_encode(p_response->firmware.version, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->firmware.addr, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->firmware.len, &p_serialized_rsp[index]);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ index += uint32_encode(p_response->crc.offset, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->crc.crc, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ index += uint32_encode(p_response->select.max_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->select.offset, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->select.crc, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_MTU_GET:
+ index += uint16_encode(p_response->mtu.size, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_PING:
+ p_serialized_rsp[index] = p_response->ping.id;
+ index += sizeof(uint8_t);
+ break;
+
+ default:
+ // no implementation
+ break;
+ }
+ }
+ else if (p_response->result == NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ index += response_ext_err_payload_add(p_serialized_rsp, index);
+ }
+
+ if (index > NRF_SERIAL_MAX_RESPONSE_SIZE)
+ {
+ NRF_LOG_ERROR("Message is larger than expected.");
+ }
+
+ // Send response.
+ if (p_transport->rsp_func((uint8_t const *)(p_serialized_rsp), index) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to send data over serial interface!");
+ }
+}
+
+
+void dfu_req_handler_rsp_clbk(nrf_dfu_response_t * p_res, void * p_context)
+{
+ nrf_dfu_serial_t * p_transport = (nrf_dfu_serial_t *)(p_context);
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_WARNING("DFU request completed with result: 0x%x", p_res->result);
+ }
+
+ switch (p_res->request)
+ {
+ default:
+ /* Reply normally.
+ * Make sure to reply to NRF_DFU_OP_OBJECT_CREATE when running DFU over serial,
+ * otherwise the transfer might run very slow, without an apparent reason.
+ */
+ break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ p_transport->pkt_notif_target_count--;
+
+ if ( (p_transport->pkt_notif_target == 0)
+ || (p_transport->pkt_notif_target_count != 0))
+ {
+ /* Do not reply to _OBJECT_WRITE messages. */
+ return;
+ }
+
+ /* Reply with a CRC message and reset the packet counter. */
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+
+ p_res->request = NRF_DFU_OP_CRC_GET;
+ p_res->crc.offset = p_res->write.offset;
+ p_res->crc.crc = p_res->write.crc;
+ } break;
+ }
+
+ response_send(p_transport, p_res);
+}
+
+
+void nrf_dfu_serial_on_packet_received(nrf_dfu_serial_t * p_transport,
+ uint8_t const * p_data,
+ uint32_t length)
+{
+ uint8_t const * p_payload = &p_data[NRF_SERIAL_OPCODE_SIZE];
+ uint16_t const payload_len = (length - NRF_SERIAL_OPCODE_SIZE);
+
+ nrf_dfu_request_t request =
+ {
+ .request = (nrf_dfu_op_t)(p_data[0]),
+ .callback.response = dfu_req_handler_rsp_clbk,
+ .p_context = p_transport
+ };
+
+ bool buf_free = true;
+
+ switch (request.request)
+ {
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ request.firmware.image_number = p_payload[0];
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ NRF_LOG_DEBUG("Set receipt notif target: %d", p_transport->pkt_notif_target);
+
+ p_transport->pkt_notif_target = uint16_decode(&p_payload[0]);
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ request.select.object_type = p_payload[0];
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ // Reset the packet receipt notification on create object
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+
+ request.create.object_type = p_payload[0];
+ request.create.object_size = uint32_decode(&p_payload[1]);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ // Buffer will be freed asynchronously
+ buf_free = false;
+
+ request.write.p_data = p_payload;
+ request.write.len = payload_len;
+ request.callback.write = p_transport->payload_free_func;
+ } break;
+
+ case NRF_DFU_OP_MTU_GET:
+ {
+ NRF_LOG_DEBUG("Received serial mtu");
+ request.mtu.size = p_transport->mtu;
+ } break;
+
+ case NRF_DFU_OP_PING:
+ {
+ NRF_LOG_DEBUG("Received ping %d", p_payload[0]);
+ request.ping.id = p_payload[0];
+ } break;
+
+ default:
+ /* Do nothing. */
+ break;
+ }
+
+ if (buf_free)
+ {
+ p_transport->payload_free_func((void *)(p_payload));
+ }
+
+ ret_code_t ret_code = nrf_dfu_req_handler_on_req(&request);
+ ASSERT(ret_code == NRF_SUCCESS);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h
new file mode 100644
index 0000000..c14ee40
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_DFU_SERIAL_H__
+#define NRF_DFU_SERIAL_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_dfu_req_handler.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial DFU Serial transports shared part
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Shared part of Device Firmware Update (DFU) transport layers using serial interface (UART, USB CDC ACM).
+ *
+ * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
+ * @ingroup nrf_dfu_serial
+ * @brief Configuration for Device Firmware Update (DFU) transport layer using UART.
+ *
+ * @defgroup nrf_dfu_serial_usb DFU Serial USB CDC ACM transport
+ * @ingroup nrf_dfu_serial
+ * @brief Configuration for Device Firmware Update (DFU) transport layer using USB CDC ACM.
+ *
+ */
+
+#define NRF_SERIAL_MAX_RESPONSE_SIZE (sizeof(nrf_dfu_response_t))
+
+/**
+ * Prototype for function for sending response over serial DFU transport.
+ */
+typedef ret_code_t (*nrf_serial_rsp_func_t)(uint8_t const * p_data, uint32_t length);
+
+/**
+ * Prototype for function for freeing RX buffer.
+ *
+ * Function is called when input data is processed.
+ */
+typedef void (*nrf_serial_rx_buf_free_func_t)(void * p_buf);
+
+
+/**@brief DFU serial transport layer state.
+ *
+ * @details This structure contains status information related to the serial transport layer type.
+ */
+typedef struct
+{
+ uint16_t pkt_notif_target;
+ uint16_t pkt_notif_target_count;
+ nrf_serial_rsp_func_t rsp_func;
+ nrf_serial_rx_buf_free_func_t payload_free_func;
+ uint32_t mtu;
+ uint8_t * p_rsp_buf;
+} nrf_dfu_serial_t;
+
+void nrf_dfu_serial_on_packet_received(nrf_dfu_serial_t * p_transport,
+ uint8_t const * p_data,
+ uint32_t length);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_SERIAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c
new file mode 100644
index 0000000..3d0b783
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_serial.h"
+
+#include <string.h>
+#include "boards.h"
+#include "app_util_platform.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_req_handler.h"
+#include "slip.h"
+#include "nrf_balloc.h"
+#include "nrf_drv_uart.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial_uart
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer using UART.
+ */
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+#define NRF_UART_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
+#define RX_BUF_SIZE (64) //to get 64bytes payload
+#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
+#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
+#define UART_SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1)
+#define BALLOC_BUF_SIZE ((CEIL_DIV((RX_BUF_SIZE+OPCODE_SIZE),sizeof(uint32_t))*sizeof(uint32_t)))
+
+NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS);
+
+static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+static uint8_t m_rx_byte;
+
+static nrf_dfu_serial_t m_serial;
+static slip_t m_slip;
+static uint8_t m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP];
+static bool m_active;
+
+static nrf_dfu_observer_t m_observer;
+
+static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const uart_dfu_transport) =
+{
+ .init_func = uart_dfu_transport_init,
+ .close_func = uart_dfu_transport_close,
+};
+
+static void payload_free(void * p_buf)
+{
+ uint8_t * p_buf_root = (uint8_t *)p_buf - DATA_OFFSET; //pointer is shifted to point to data
+ nrf_balloc_free(&m_payload_pool, p_buf_root);
+}
+
+static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
+{
+ uint32_t slip_len;
+ (void) slip_encode(m_rsp_buf, (uint8_t *)p_data, length, &slip_len);
+
+ return nrf_drv_uart_tx(&m_uart, m_rsp_buf, slip_len);
+}
+
+static __INLINE void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
+{
+ ret_code_t ret_code;
+
+ ret_code = slip_decode_add_byte(&m_slip, p_data[0]);
+ (void) nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ // Activity detected on current transport, close all except active one.
+ UNUSED_RETURN_VALUE(nrf_dfu_transports_close(&uart_dfu_transport));
+
+ nrf_dfu_serial_on_packet_received(p_transport,
+ (uint8_t const *)m_slip.p_buffer,
+ m_slip.current_index);
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Failed to allocate buffer");
+ return;
+ }
+ NRF_LOG_INFO("Allocated buffer %x", p_rx_buf);
+ // reset the slip decoding
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.state = SLIP_STATE_DECODING;
+ }
+
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ on_rx_complete((nrf_dfu_serial_t*)p_context,
+ p_event->data.rxtx.p_data,
+ p_event->data.rxtx.bytes);
+ break;
+
+ case NRF_DRV_UART_EVT_ERROR:
+ APP_ERROR_HANDLER(p_event->data.error.error_mask);
+ break;
+
+ default:
+ // No action.
+ break;
+ }
+}
+
+static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_active)
+ {
+ return err_code;
+ }
+
+ NRF_LOG_DEBUG("serial_dfu_transport_init()");
+
+ m_observer = observer;
+
+ err_code = nrf_balloc_init(&m_payload_pool);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.buffer_len = UART_SLIP_MTU;
+ m_slip.state = SLIP_STATE_DECODING;
+
+ m_serial.rsp_func = rsp_send;
+ m_serial.payload_free_func = payload_free;
+ m_serial.mtu = UART_SLIP_MTU;
+ m_serial.p_rsp_buf = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP -
+ NRF_SERIAL_MAX_RESPONSE_SIZE];
+
+ nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
+
+ uart_config.pseltxd = TX_PIN_NUMBER;
+ uart_config.pselrxd = RX_PIN_NUMBER;
+ uart_config.pselcts = CTS_PIN_NUMBER;
+ uart_config.pselrts = RTS_PIN_NUMBER;
+ uart_config.hwfc = NRF_DFU_SERIAL_UART_USES_HWFC ?
+ NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
+ uart_config.p_context = &m_serial;
+
+ err_code = nrf_drv_uart_init(&m_uart, &uart_config, uart_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed initializing uart");
+ return err_code;
+ }
+
+ err_code = nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed initializing rx");
+ }
+
+ NRF_LOG_DEBUG("serial_dfu_transport_init() completed");
+
+ m_active = true;
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+
+ return err_code;
+}
+
+
+static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ if ((m_active == true) && (p_exception != &uart_dfu_transport))
+ {
+ nrf_drv_uart_uninit(&m_uart);
+ m_active = false;
+ }
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c
new file mode 100644
index 0000000..2b45643
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c
@@ -0,0 +1,370 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_transport.h"
+#include "slip.h"
+#include "nrf_balloc.h"
+#include "nrf_drv_power.h"
+#include "nrf_drv_clock.h"
+#include "nrf_drv_usbd.h"
+#include "nrf_dfu_serial.h"
+#include "app_scheduler.h"
+#include "app_usbd.h"
+#include "app_usbd_cdc_acm.h"
+#include "app_usbd_core.h"
+#include "app_usbd_string_desc.h"
+#include "app_util_platform.h"
+#include "app_usbd_serial_num.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial_usb
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial_usb DFU Serial USB CDC ACM transport
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer using USB CDC ACM.
+ */
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+
+#define NRF_USB_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
+
+#define RX_BUF_SIZE (1024)
+#define SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1)
+#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
+#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
+
+#define CDC_ACM_COMM_INTERFACE 0
+#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
+#define CDC_ACM_DATA_INTERFACE 1
+#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
+#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
+
+/**
+ * @brief Enable power USB detection
+ *
+ * Configure if example supports USB port connection
+ */
+#ifndef USBD_POWER_DETECTION
+#define USBD_POWER_DETECTION true
+#endif
+
+/**
+ * @brief Interfaces list passed to @ref APP_USBD_CDC_ACM_GLOBAL_DEF
+ * */
+#define CDC_ACM_INTERFACES_CONFIG() \
+ APP_USBD_CDC_ACM_CONFIG(CDC_ACM_COMM_INTERFACE, \
+ CDC_ACM_COMM_EPIN, \
+ CDC_ACM_DATA_INTERFACE, \
+ CDC_ACM_DATA_EPIN, \
+ CDC_ACM_DATA_EPOUT)
+
+/*lint -save -e26 -e64 -e505 -e651 */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+
+/**@brief CDC_ACM class instance. */
+APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
+ cdc_acm_user_ev_handler,
+ CDC_ACM_COMM_INTERFACE,
+ CDC_ACM_DATA_INTERFACE,
+ CDC_ACM_COMM_EPIN,
+ CDC_ACM_DATA_EPIN,
+ CDC_ACM_DATA_EPOUT,
+ APP_USBD_CDC_COMM_PROTOCOL_NONE);
+/*lint -restore */
+
+NRF_BALLOC_DEF(m_payload_pool, (SLIP_MTU+1), NRF_DFU_SERIAL_USB_RX_BUFFERS);
+
+static nrf_dfu_serial_t m_serial;
+static slip_t m_slip;
+static uint8_t m_rsp_buf[NRF_USB_MAX_RESPONSE_SIZE_SLIP];
+static uint8_t m_rx_buf[NRF_DRV_USBD_EPSIZE];
+
+static nrf_dfu_observer_t m_observer;
+
+static uint32_t usb_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t usb_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const usb_dfu_transport) =
+{
+ .init_func = usb_dfu_transport_init,
+ .close_func = usb_dfu_transport_close,
+};
+
+
+static void payload_free(void * p_buf)
+{
+ uint8_t * p_buf_root = ((uint8_t *)(p_buf)) - DATA_OFFSET; //pointer is shifted to point to data
+ nrf_balloc_free(&m_payload_pool, p_buf_root);
+}
+
+
+static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
+{
+ ASSERT(p_data);
+ ASSERT(length != 0);
+
+ uint32_t slip_len;
+
+ // Cannot fail if inputs are non-NULL.
+ (void) slip_encode(m_rsp_buf, (uint8_t *)(p_data), length, &slip_len);
+
+ return app_usbd_cdc_acm_write(&m_app_cdc_acm, m_rsp_buf, slip_len);
+}
+
+
+static void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
+{
+ ret_code_t ret_code;
+
+ for (uint32_t i = 0; i < len; i++)
+ {
+ ret_code = slip_decode_add_byte(&m_slip, p_data[i]);
+ if (ret_code != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ // Activity detected on current transport, close all except active one.
+ (void) nrf_dfu_transports_close(&usb_dfu_transport);
+
+ nrf_dfu_serial_on_packet_received(p_transport,
+ (uint8_t const *)(m_slip.p_buffer),
+ m_slip.current_index);
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Failed to allocate buffer!");
+ return;
+ }
+
+ NRF_LOG_DEBUG("Allocated buffer %x", p_rx_buf);
+ // reset the slip decoding
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.state = SLIP_STATE_DECODING;
+ }
+}
+
+/**
+ * @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t (headphones)
+ * */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ ret_code_t ret_code;
+
+ switch (event)
+ {
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+ {
+ ret_code = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buf, 1);
+ NRF_LOG_WARNING("Could not read from CDC. Error: 0x%x.", ret_code);
+ } break;
+
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+ {
+ do
+ {
+ on_rx_complete(&m_serial, m_rx_buf, 1);
+ ret_code = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buf, 1);
+ } while (ret_code == NRF_SUCCESS);
+ } break;
+
+ default:
+ break;
+ }
+}
+
+
+static void usbd_dfu_transport_ev_handler(app_usbd_event_type_t event)
+{
+ switch (event)
+ {
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_disable();
+ break;
+
+ case APP_USBD_EVT_POWER_DETECTED:
+ NRF_LOG_INFO("USB power detected");
+ if (!nrf_drv_usbd_is_enabled())
+ {
+ app_usbd_enable();
+ }
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+ break;
+
+ case APP_USBD_EVT_POWER_REMOVED:
+ NRF_LOG_INFO("USB power removed");
+ app_usbd_stop();
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_DEACTIVATED);
+ }
+ break;
+
+ case APP_USBD_EVT_POWER_READY:
+ NRF_LOG_INFO("USB ready");
+ app_usbd_start();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void usbd_sched_event_handler(void * p_event_data, uint16_t event_size)
+{
+ app_usbd_event_execute(p_event_data);
+}
+
+
+static void usbd_event_handler(app_usbd_internal_evt_t const * const p_event)
+{
+ ret_code_t ret_code;
+ if (p_event->type == APP_USBD_EVT_DRV_SOF)
+ {
+ app_usbd_event_execute(p_event);
+ }
+ else
+ {
+ ret_code = app_sched_event_put(p_event,
+ sizeof(app_usbd_internal_evt_t),
+ usbd_sched_event_handler);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not schedule USB event!");
+ }
+ }
+}
+
+
+static uint32_t usb_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code;
+
+ /* Execute event directly in interrupt handler */
+ static const app_usbd_config_t usbd_config =
+ {
+ .ev_handler = usbd_event_handler,
+ .ev_state_proc = usbd_dfu_transport_ev_handler
+ };
+
+ (void) nrf_balloc_init(&m_payload_pool); //Result is checked by checking result of _alloc().
+
+ m_observer = observer;
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Could not allocate payload pool.");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.buffer_len = SLIP_MTU;
+ m_slip.state = SLIP_STATE_DECODING;
+
+ m_serial.rsp_func = rsp_send;
+ m_serial.payload_free_func = payload_free;
+ m_serial.mtu = SLIP_MTU;
+ m_serial.p_rsp_buf = &m_rsp_buf[NRF_USB_MAX_RESPONSE_SIZE_SLIP -
+ NRF_SERIAL_MAX_RESPONSE_SIZE];
+
+
+ NRF_LOG_DEBUG("Initializing drivers.");
+
+ err_code = nrf_drv_clock_init();
+ if (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)
+ {
+ VERIFY_SUCCESS(err_code);
+ }
+
+ err_code = nrf_drv_power_init(NULL);
+ VERIFY_SUCCESS(err_code);
+
+ app_usbd_serial_num_generate();
+
+ err_code = app_usbd_init(&usbd_config);
+ VERIFY_SUCCESS(err_code);
+
+ app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
+ err_code = app_usbd_class_append(class_cdc_acm);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Starting USB");
+
+ if (USBD_POWER_DETECTION)
+ {
+ err_code = app_usbd_power_events_enable();
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No USB power detection enabled, starting USB now");
+
+ app_usbd_enable();
+ app_usbd_start();
+ }
+
+ NRF_LOG_DEBUG("USB Transport initialized");
+
+ return err_code;
+}
+
+
+static uint32_t usb_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c
new file mode 100644
index 0000000..3bf4d00
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c
@@ -0,0 +1,637 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "bsp.h"
+#include <stddef.h>
+#include <stdio.h>
+#include "nordic_common.h"
+#include "nrf.h"
+#include "nrf_gpio.h"
+#include "nrf_error.h"
+#include "bsp_config.h"
+#include "boards.h"
+
+#ifndef BSP_SIMPLE
+#include "app_timer.h"
+#include "app_button.h"
+#endif // BSP_SIMPLE
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+static bsp_indication_t m_stable_state = BSP_INDICATE_IDLE;
+static bool m_leds_clear = false;
+static uint32_t m_indication_type = 0;
+static bool m_alert_on = false;
+APP_TIMER_DEF(m_bsp_leds_tmr);
+APP_TIMER_DEF(m_bsp_alert_tmr);
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+#if BUTTONS_NUMBER > 0
+#ifndef BSP_SIMPLE
+static bsp_event_callback_t m_registered_callback = NULL;
+static bsp_button_event_cfg_t m_events_list[BUTTONS_NUMBER] = {{BSP_EVENT_NOTHING, BSP_EVENT_NOTHING}};
+APP_TIMER_DEF(m_bsp_button_tmr);
+static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action);
+#endif // BSP_SIMPLE
+
+#ifndef BSP_SIMPLE
+static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
+{
+ #ifdef BSP_BUTTON_0
+ {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_0
+
+ #ifdef BSP_BUTTON_1
+ {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_1
+
+ #ifdef BSP_BUTTON_2
+ {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_2
+
+ #ifdef BSP_BUTTON_3
+ {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_3
+
+ #ifdef BSP_BUTTON_4
+ {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_4
+
+ #ifdef BSP_BUTTON_5
+ {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_5
+
+ #ifdef BSP_BUTTON_6
+ {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_6
+
+ #ifdef BSP_BUTTON_7
+ {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_7
+
+};
+#endif // BSP_SIMPLE
+#endif // BUTTONS_NUMBER > 0
+
+#if (BUTTONS_NUMBER > 0)
+bool bsp_button_is_pressed(uint32_t button)
+{
+ if (button < BUTTONS_NUMBER)
+ {
+ return bsp_board_button_state_get(button);
+ }
+ else
+ {
+ //If button is not present always return false
+ return false;
+ }
+}
+#endif
+
+#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+/**@brief Function for handling button events.
+ *
+ * @param[in] pin_no The pin number of the button pressed.
+ * @param[in] button_action Action button.
+ */
+static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)
+{
+ bsp_event_t event = BSP_EVENT_NOTHING;
+ uint32_t button = 0;
+ uint32_t err_code;
+ static uint8_t current_long_push_pin_no; /**< Pin number of a currently pushed button, that could become a long push if held long enough. */
+ static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */
+
+ button = bsp_board_pin_to_button_idx(pin_no);
+
+ if (button < BUTTONS_NUMBER)
+ {
+ switch (button_action)
+ {
+ case APP_BUTTON_PUSH:
+ event = m_events_list[button].push_event;
+ if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING)
+ {
+ err_code = app_timer_start(m_bsp_button_tmr, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);
+ if (err_code == NRF_SUCCESS)
+ {
+ current_long_push_pin_no = pin_no;
+ }
+ }
+ release_event_at_push[button] = m_events_list[button].release_event;
+ break;
+ case APP_BUTTON_RELEASE:
+ (void)app_timer_stop(m_bsp_button_tmr);
+ if (release_event_at_push[button] == m_events_list[button].release_event)
+ {
+ event = m_events_list[button].release_event;
+ }
+ break;
+ case BSP_BUTTON_ACTION_LONG_PUSH:
+ event = m_events_list[button].long_push_event;
+ }
+ }
+
+ if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))
+ {
+ m_registered_callback(event);
+ }
+}
+
+/**@brief Handle events from button timer.
+ *
+ * @param[in] p_context parameter registered in timer start function.
+ */
+static void button_timer_handler(void * p_context)
+{
+ bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH);
+}
+
+
+#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+static void leds_off(void)
+{
+ if (m_alert_on)
+ {
+ uint32_t i;
+ for (i = 0; i < LEDS_NUMBER; i++)
+ {
+ if (i != BSP_LED_ALERT)
+ {
+ bsp_board_led_off(i);
+ }
+ }
+ }
+ else
+ {
+ bsp_board_leds_off();
+ }
+}
+
+
+/**@brief Configure leds to indicate required state.
+ * @param[in] indicate State to be indicated.
+ */
+static uint32_t bsp_led_indication(bsp_indication_t indicate)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t next_delay = 0;
+
+ if (m_leds_clear)
+ {
+ m_leds_clear = false;
+ leds_off();
+ }
+
+ switch (indicate)
+ {
+ case BSP_INDICATE_IDLE:
+ leds_off();
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_SCANNING:
+ case BSP_INDICATE_ADVERTISING:
+ // in advertising blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_INDICATE_ADVERTISING))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_INDICATE_ADVERTISING);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_INDICATE_ADVERTISING);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_ADVERTISING_WHITELIST:
+ // in advertising quickly blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_WHITELIST))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_WHITELIST);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_WHITELIST ?
+ ADVERTISING_WHITELIST_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_WHITELIST);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_WHITELIST ?
+ ADVERTISING_WHITELIST_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_ADVERTISING_SLOW:
+ // in advertising slowly blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_SLOW))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_SLOW);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_SLOW);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_ADVERTISING_DIRECTED:
+ // in advertising very quickly blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_DIRECTED))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_DIRECTED);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_DIRECTED ?
+ ADVERTISING_DIRECTED_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_DIRECTED);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_DIRECTED ?
+ ADVERTISING_DIRECTED_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_BONDING:
+ // in bonding fast blink LED_0
+ bsp_board_led_invert(BSP_LED_INDICATE_BONDING);
+
+ m_stable_state = indicate;
+ err_code =
+ app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(BONDING_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_CONNECTED:
+ bsp_board_led_on(BSP_LED_INDICATE_CONNECTED);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_SENT_OK:
+ // when sending shortly invert LED_1
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_SENT_OK);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(SENT_OK_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_SEND_ERROR:
+ // on receving error invert LED_1 for long time
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_SEND_ERROR);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(SEND_ERROR_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_RCV_OK:
+ // when receving shortly invert LED_1
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_RCV_OK);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(RCV_OK_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_RCV_ERROR:
+ // on receving error invert LED_1 for long time
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_RCV_ERROR);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(RCV_ERROR_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_FATAL_ERROR:
+ // on fatal error turn on all leds
+ bsp_board_leds_on();
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_ALERT_0:
+ case BSP_INDICATE_ALERT_1:
+ case BSP_INDICATE_ALERT_2:
+ case BSP_INDICATE_ALERT_3:
+ case BSP_INDICATE_ALERT_OFF:
+ err_code = app_timer_stop(m_bsp_alert_tmr);
+ next_delay = (uint32_t)BSP_INDICATE_ALERT_OFF - (uint32_t)indicate;
+
+ // a little trick to find out that if it did not fall through ALERT_OFF
+ if (next_delay && (err_code == NRF_SUCCESS))
+ {
+ if (next_delay > 1)
+ {
+ err_code = app_timer_start(m_bsp_alert_tmr,
+ APP_TIMER_TICKS(((uint16_t)next_delay * ALERT_INTERVAL)),
+ NULL);
+ }
+ bsp_board_led_on(BSP_LED_ALERT);
+ m_alert_on = true;
+ }
+ else
+ {
+ bsp_board_led_off(BSP_LED_ALERT);
+ m_alert_on = false;
+
+ }
+ break;
+
+ case BSP_INDICATE_USER_STATE_OFF:
+ leds_off();
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_0:
+ leds_off();
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED1);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_1:
+ leds_off();
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED2);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_2:
+ leds_off();
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED1);
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED2);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_3:
+
+ case BSP_INDICATE_USER_STATE_ON:
+ bsp_board_leds_on();
+ m_stable_state = indicate;
+ break;
+
+ default:
+ break;
+ }
+
+ return err_code;
+}
+
+
+/**@brief Handle events from leds timer.
+ *
+ * @note Timer handler does not support returning an error code.
+ * Errors from bsp_led_indication() are not propagated.
+ *
+ * @param[in] p_context parameter registered in timer start function.
+ */
+static void leds_timer_handler(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ if (m_indication_type & BSP_INIT_LEDS)
+ {
+ UNUSED_VARIABLE(bsp_led_indication(m_stable_state));
+ }
+}
+
+
+/**@brief Handle events from alert timer.
+ *
+ * @param[in] p_context parameter registered in timer start function.
+ */
+static void alert_timer_handler(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ bsp_board_led_invert(BSP_LED_ALERT);
+}
+#endif // #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+
+/**@brief Configure indicators to required state.
+ */
+uint32_t bsp_indication_set(bsp_indication_t indicate)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+ if (m_indication_type & BSP_INIT_LEDS)
+ {
+ err_code = bsp_led_indication(indicate);
+ }
+
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+ return err_code;
+}
+
+
+uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+ m_indication_type = type;
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+ m_registered_callback = callback;
+
+ // BSP will support buttons and generate events
+ if (type & BSP_INIT_BUTTONS)
+ {
+ uint32_t num;
+
+ for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
+ {
+ err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_button_init((app_button_cfg_t *)app_buttons,
+ BUTTONS_NUMBER,
+ APP_TIMER_TICKS(50));
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_button_enable();
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_timer_create(&m_bsp_button_tmr,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ button_timer_handler);
+ }
+ }
+#elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE)
+ bsp_board_init(type);
+#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+ if (type & BSP_INIT_LEDS)
+ {
+ //handle LEDs only. Buttons are already handled.
+ bsp_board_init(BSP_INIT_LEDS);
+
+ // timers module must be already initialized!
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code =
+ app_timer_create(&m_bsp_leds_tmr, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code =
+ app_timer_create(&m_bsp_alert_tmr, APP_TIMER_MODE_REPEATED, alert_timer_handler);
+ }
+ }
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+ return err_code;
+}
+
+
+#ifndef BSP_SIMPLE
+/**@brief Assign specific event to button.
+ */
+uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#if BUTTONS_NUMBER > 0
+ if (button < BUTTONS_NUMBER)
+ {
+ if (event == BSP_EVENT_DEFAULT)
+ {
+ // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions.
+ event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;
+ }
+ switch (action)
+ {
+ case BSP_BUTTON_ACTION_PUSH:
+ m_events_list[button].push_event = event;
+ break;
+ case BSP_BUTTON_ACTION_LONG_PUSH:
+ m_events_list[button].long_push_event = event;
+ break;
+ case BSP_BUTTON_ACTION_RELEASE:
+ m_events_list[button].release_event = event;
+ break;
+ default:
+ err_code = NRF_ERROR_INVALID_PARAM;
+ break;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+#else
+ err_code = NRF_ERROR_INVALID_PARAM;
+#endif // BUTTONS_NUMBER > 0
+
+ return err_code;
+}
+
+#endif // BSP_SIMPLE
+
+
+uint32_t bsp_buttons_enable()
+{
+#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE)
+ return app_button_enable();
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+uint32_t bsp_buttons_disable()
+{
+#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE)
+ return app_button_disable();
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+static uint32_t wakeup_button_cfg(uint32_t button_idx, bool enable)
+{
+#if !defined(BSP_SIMPLE)
+ if (button_idx < BUTTONS_NUMBER)
+ {
+ nrf_gpio_pin_sense_t sense = enable ?
+ (BUTTONS_ACTIVE_STATE ? NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW) :
+ NRF_GPIO_PIN_NOSENSE;
+ nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), sense);
+ return NRF_SUCCESS;
+ }
+#else
+ UNUSED_PARAMETER(button_idx);
+ UNUSED_PARAMETER(enable);
+#endif
+ return NRF_ERROR_NOT_SUPPORTED;
+
+}
+uint32_t bsp_wakeup_button_enable(uint32_t button_idx)
+{
+ return wakeup_button_cfg(button_idx, true);
+}
+
+uint32_t bsp_wakeup_button_disable(uint32_t button_idx)
+{
+ return wakeup_button_cfg(button_idx, false);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h
new file mode 100644
index 0000000..904a3d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h
@@ -0,0 +1,307 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup bsp Board Support Package
+ * @{
+ * @ingroup app_common
+ *
+ * @brief BSP module.
+ * @details This module provides a layer of abstraction from the board.
+ * It allows the user to indicate certain states on LEDs in a simple way.
+ * Module functionality can be modified by defining BSP_SIMPLE to reduce
+ * functionality of this module to enable and read state of the buttons.
+ */
+
+#ifndef BSP_H__
+#define BSP_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "boards.h"
+
+#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE)
+#include "app_button.h"
+
+#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */
+
+#endif
+
+/* BSP_UART_SUPPORT
+ * This define enables UART support module.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8_t bsp_button_action_t; /**< The different actions that can be performed on a button. */
+
+#define BSP_INDICATIONS_LIST { \
+ "BSP_INDICATE_IDLE", \
+ "BSP_INDICATE_SCANNING", \
+ "BSP_INDICATE_ADVERTISING", \
+ "BSP_INDICATE_ADVERTISING_WHITELIST", \
+ "BSP_INDICATE_ADVERTISING_SLOW", \
+ "BSP_INDICATE_ADVERTISING_DIRECTED", \
+ "BSP_INDICATE_BONDING", \
+ "BSP_INDICATE_CONNECTED", \
+ "BSP_INDICATE_SENT_OK", \
+ "BSP_INDICATE_SEND_ERROR", \
+ "BSP_INDICATE_RCV_OK", \
+ "BSP_INDICATE_RCV_ERROR", \
+ "BSP_INDICATE_FATAL_ERROR", \
+ "BSP_INDICATE_ALERT_0", \
+ "BSP_INDICATE_ALERT_1", \
+ "BSP_INDICATE_ALERT_2", \
+ "BSP_INDICATE_ALERT_3", \
+ "BSP_INDICATE_ALERT_OFF", \
+ "BSP_INDICATE_USER_STATE_OFF", \
+ "BSP_INDICATE_USER_STATE_0", \
+ "BSP_INDICATE_USER_STATE_1", \
+ "BSP_INDICATE_USER_STATE_2", \
+ "BSP_INDICATE_USER_STATE_3", \
+ "BSP_INDICATE_USER_STATE_ON" \
+} /**< See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.*/
+
+
+/**@brief BSP indication states.
+ *
+ * @details See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.
+ */
+typedef enum
+{
+ BSP_INDICATE_FIRST = 0,
+ BSP_INDICATE_IDLE = BSP_INDICATE_FIRST, /**< See \ref BSP_INDICATE_IDLE.*/
+ BSP_INDICATE_SCANNING, /**< See \ref BSP_INDICATE_SCANNING.*/
+ BSP_INDICATE_ADVERTISING, /**< See \ref BSP_INDICATE_ADVERTISING.*/
+ BSP_INDICATE_ADVERTISING_WHITELIST, /**< See \ref BSP_INDICATE_ADVERTISING_WHITELIST.*/
+ BSP_INDICATE_ADVERTISING_SLOW, /**< See \ref BSP_INDICATE_ADVERTISING_SLOW.*/
+ BSP_INDICATE_ADVERTISING_DIRECTED, /**< See \ref BSP_INDICATE_ADVERTISING_DIRECTED.*/
+ BSP_INDICATE_BONDING, /**< See \ref BSP_INDICATE_BONDING.*/
+ BSP_INDICATE_CONNECTED, /**< See \ref BSP_INDICATE_CONNECTED.*/
+ BSP_INDICATE_SENT_OK, /**< See \ref BSP_INDICATE_SENT_OK.*/
+ BSP_INDICATE_SEND_ERROR, /**< See \ref BSP_INDICATE_SEND_ERROR.*/
+ BSP_INDICATE_RCV_OK, /**< See \ref BSP_INDICATE_RCV_OK.*/
+ BSP_INDICATE_RCV_ERROR, /**< See \ref BSP_INDICATE_RCV_ERROR.*/
+ BSP_INDICATE_FATAL_ERROR, /**< See \ref BSP_INDICATE_FATAL_ERROR.*/
+ BSP_INDICATE_ALERT_0, /**< See \ref BSP_INDICATE_ALERT_0.*/
+ BSP_INDICATE_ALERT_1, /**< See \ref BSP_INDICATE_ALERT_1.*/
+ BSP_INDICATE_ALERT_2, /**< See \ref BSP_INDICATE_ALERT_2.*/
+ BSP_INDICATE_ALERT_3, /**< See \ref BSP_INDICATE_ALERT_3.*/
+ BSP_INDICATE_ALERT_OFF, /**< See \ref BSP_INDICATE_ALERT_OFF.*/
+ BSP_INDICATE_USER_STATE_OFF, /**< See \ref BSP_INDICATE_USER_STATE_OFF.*/
+ BSP_INDICATE_USER_STATE_0, /**< See \ref BSP_INDICATE_USER_STATE_0.*/
+ BSP_INDICATE_USER_STATE_1, /**< See \ref BSP_INDICATE_USER_STATE_1.*/
+ BSP_INDICATE_USER_STATE_2, /**< See \ref BSP_INDICATE_USER_STATE_2.*/
+ BSP_INDICATE_USER_STATE_3, /**< See \ref BSP_INDICATE_USER_STATE_3.*/
+ BSP_INDICATE_USER_STATE_ON, /**< See \ref BSP_INDICATE_USER_STATE_ON.*/
+ BSP_INDICATE_LAST = BSP_INDICATE_USER_STATE_ON
+} bsp_indication_t;
+
+/**@brief BSP events.
+ *
+ * @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons.
+ */
+typedef enum
+{
+ BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */
+ BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */
+ BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */
+ BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */
+ BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */
+ BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */
+ BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */
+ BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */
+ BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */
+ BSP_EVENT_RESET, /**< The device should reset. */
+ BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */
+ BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */
+ BSP_EVENT_SYSOFF, /**< The device should enter system off mode (without wakeup). */
+ BSP_EVENT_DFU, /**< The device should enter DFU mode. */
+ BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */
+ BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */
+ BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */
+ BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */
+ BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */
+ BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */
+ BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */
+ BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */
+ BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7,
+} bsp_event_t;
+
+
+typedef struct
+{
+ bsp_event_t push_event; /**< The event to fire on regular button press. */
+ bsp_event_t long_push_event; /**< The event to fire on long button press. */
+ bsp_event_t release_event; /**< The event to fire on button release. */
+} bsp_button_event_cfg_t;
+
+/**@brief BSP module event callback function type.
+ *
+ * @details Upon an event in the BSP module, this callback function will be called to notify
+ * the application about the event.
+ *
+ * @param[in] bsp_event_t BSP event type.
+ */
+typedef void (* bsp_event_callback_t)(bsp_event_t);
+
+
+/**@brief Function for initializing BSP.
+ *
+ * @details The function initializes the board support package to allow state indication and
+ * button reaction. Default events are assigned to buttons.
+ * @note Before calling this function, you must initiate the following required modules:
+ * - @ref app_timer for LED support
+ * - @ref app_gpiote for button support
+ *
+ * @param[in] type Type of peripherals used.
+ * @param[in] callback Function to be called when button press/event is detected.
+ *
+ * @retval NRF_SUCCESS If the BSP module was successfully initialized.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized.
+ * @retval NRF_ERROR_NO_MEM If the maximum number of timers has already been reached.
+ * @retval NRF_ERROR_INVALID_PARAM If GPIOTE has too many users.
+ * @retval NRF_ERROR_INVALID_STATE If button or GPIOTE has not been initialized.
+ */
+uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback);
+
+
+/**@brief Function for checking button states.
+ *
+ * @details This function checks if the button is pressed. If the button ID is out of range,
+ * the function returns false.
+ *
+ * @param[in] button Button ID to check.
+ *
+ * @retval true If the button is pressed.
+ * @retval false If the button is not pressed.
+ */
+bool bsp_button_is_pressed(uint32_t button);
+
+
+/**@brief Function for assigning a specific event to a button.
+ *
+ * @details This function allows redefinition of standard events assigned to buttons.
+ * To unassign events, provide the event @ref BSP_EVENT_NOTHING.
+ *
+ * @param[in] button Button ID to be redefined.
+ * @param[in] action Button action to assign event to.
+ * @param[in] event Event to be assigned to button.
+ *
+ * @retval NRF_SUCCESS If the event was successfully assigned to button.
+ * @retval NRF_ERROR_INVALID_PARAM If the button ID or button action was invalid.
+ */
+uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event);
+
+
+/**@brief Function for configuring indicators to required state.
+ *
+ * @details This function indicates the required state by means of LEDs (if enabled).
+ *
+ * @note Alerts are indicated independently.
+ *
+ * @param[in] indicate State to be indicated.
+ *
+ * @retval NRF_SUCCESS If the state was successfully indicated.
+ * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized,
+ * or internal timer has not been created.
+ */
+uint32_t bsp_indication_set(bsp_indication_t indicate);
+
+
+/**@brief Function for enabling all buttons.
+ *
+ * @details After calling this function, all buttons will generate events when pressed, and
+ * all buttons will be able to wake the system up from sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were successfully enabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ * @return A propagated error.
+ */
+uint32_t bsp_buttons_enable(void);
+
+
+/**@brief Function for disabling all buttons.
+ *
+ * @details After calling this function, no buttons will generate events when pressed, and
+ * no buttons will be able to wake the system up from sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were successfully disabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ * @return A propagated error.
+ */
+uint32_t bsp_buttons_disable(void);
+
+
+/**@brief Function for enabling wakeup from SYSTEM OFF for given button.
+ *
+ * @details After calling this function, button can be used to wake up the chip.
+ * This function should only be called immediately before going into sleep.
+ *
+ * @param[in] button_idx Index of the button.
+ *
+ * @retval NRF_SUCCESS If the button was successfully enabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ */
+uint32_t bsp_wakeup_button_enable(uint32_t button_idx);
+
+
+/**@brief Function for disabling wakeup for the given button.
+ *
+ * @param[in] button_idx index of the button.
+ *
+ * @retval NRF_SUCCESS If the button was successfully disabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ */
+uint32_t bsp_wakeup_button_disable(uint32_t button_idx);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BSP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c
new file mode 100644
index 0000000..6706da9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BSP_BTN_ANT)
+#include "bsp_btn_ant.h"
+#include "nrf_sdh_ant.h"
+#include "bsp.h"
+
+
+static bool m_connected = false; /**< Notify if channel is connected. */
+static uint8_t m_channel = UINT8_MAX; /**< ANT channel number linked to indication. */
+static uint8_t m_channel_type; /**< Type of linked ANT channel. */
+
+/**@brief Function for configuring the buttons for connection.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static ret_code_t connection_buttons_configure(void)
+{
+ ret_code_t err_code = bsp_event_to_button_action_assign(BSP_BTN_ANT_CONFIG_SLEEP_BTN_ID,
+ BSP_BUTTON_ACTION_RELEASE,
+ BSP_EVENT_DEFAULT);
+ if (err_code == NRF_ERROR_INVALID_PARAM)
+ {
+ return NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+/**@brief Function for configuring the buttons for searching.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static ret_code_t searching_buttons_configure(void)
+{
+ ret_code_t err_code = bsp_event_to_button_action_assign(BSP_BTN_ANT_CONFIG_SLEEP_BTN_ID,
+ BSP_BUTTON_ACTION_RELEASE,
+ BSP_EVENT_SLEEP);
+ if (err_code == NRF_ERROR_INVALID_PARAM)
+ {
+ return NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t bsp_btn_ant_sleep_mode_prepare(void)
+{
+ ret_code_t err_code = bsp_buttons_disable();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = bsp_wakeup_button_enable(BSP_BTN_ANT_CONFIG_WAKEUP_BTN_ID);
+ if (err_code == NRF_ERROR_NOT_SUPPORTED)
+ {
+ return NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+/**
+ * @brief Function for handling ANT events.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Context.
+ */
+static void ant_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_channel != p_ant_evt->channel)
+ {
+ return;
+ }
+
+ switch (m_channel_type)
+ {
+ case CHANNEL_TYPE_SLAVE:
+ /* fall through */
+ case CHANNEL_TYPE_SLAVE_RX_ONLY:
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+ if (!m_connected)
+ {
+ err_code = connection_buttons_configure();
+ }
+
+ m_connected = true;
+ break;
+
+ case EVENT_RX_FAIL_GO_TO_SEARCH:
+ m_connected = false;
+
+ err_code = searching_buttons_configure();
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ APP_ERROR_CHECK(err_code);
+}
+
+NRF_SDH_ANT_OBSERVER(m_ant_observer, BSP_BTN_ANT_OBSERVER_PRIO, ant_evt_handler, NULL);
+
+ret_code_t bsp_btn_ant_init(uint8_t channel, uint8_t channel_type)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ m_channel = channel;
+ m_channel_type = channel_type;
+
+ if (!m_connected)
+ {
+ err_code = searching_buttons_configure();
+ }
+ else
+ {
+ err_code = connection_buttons_configure();
+ }
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(BSP_BTN_ANT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h
new file mode 100644
index 0000000..061fc72
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup bsp_btn_ant BSP: ANT Button Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for controlling ANT behavior through button actions.
+ *
+ * @details The application must propagate ANT events to the ANT Button Module.
+ * Based on these events, the ANT Button Module configures the Board Support Package
+ * to generate BSP events for certain button actions. These BSP events should then be
+ * handled by the application's BSP event handler.
+ *
+ */
+
+#ifndef BSP_BTN_ANT_H__
+#define BSP_BTN_ANT_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**@brief Function for initializing the ANT Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons.
+ *
+ * @param[in] channel ANT channel number.
+ * @param[in] channel_type ANT channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is
+ * returned.
+ */
+ret_code_t bsp_btn_ant_init(uint8_t channel, uint8_t channel_type);
+
+/**@brief Function for setting up wakeup buttons before going into sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t bsp_btn_ant_sleep_mode_prepare(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_BTN_ANT_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c
new file mode 100644
index 0000000..65d7a4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c
@@ -0,0 +1,254 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "bsp_btn_ble.h"
+#include "nrf_sdh_ble.h"
+#include "bsp.h"
+
+#define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */
+#define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */
+#define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */
+#define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */
+#define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */
+
+#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */
+#define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */
+#define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */
+
+/**@brief This macro will return from the current function if err_code
+ * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM.
+ */
+#define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \
+do \
+{ \
+ if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \
+ { \
+ return err_code; \
+ } \
+} \
+while (0)
+
+
+/**@brief This macro will return from the current function if err_code
+ * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED.
+ */
+#define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \
+do \
+{ \
+ if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \
+ { \
+ return err_code; \
+ } \
+} \
+while (0)
+
+
+/**@brief This macro will call the registered error handler if err_code
+ * is not NRF_SUCCESS and the error handler is not NULL.
+ */
+#define CALL_HANDLER_ON_ERROR(err_code) \
+do \
+{ \
+ if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \
+ { \
+ m_error_handler(err_code); \
+ } \
+} \
+while (0)
+
+
+static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */
+static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */
+
+
+/**@brief Function for configuring the buttons for connection.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static uint32_t connection_buttons_configure()
+{
+ uint32_t err_code;
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_DEFAULT);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
+ BTN_ACTION_WHITELIST_OFF,
+ BSP_EVENT_WHITELIST_OFF);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
+ BTN_ACTION_DISCONNECT,
+ BSP_EVENT_DISCONNECT);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for configuring the buttons for advertisement.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static uint32_t advertising_buttons_configure()
+{
+ uint32_t err_code;
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
+ BTN_ACTION_DISCONNECT,
+ BSP_EVENT_DEFAULT);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
+ BTN_ACTION_WHITELIST_OFF,
+ BSP_EVENT_WHITELIST_OFF);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_SLEEP);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for extracting the BSP event valid at startup.
+ *
+ * @details When a button was used to wake up the device, the button press will not generate an
+ * interrupt. This function reads which button was pressed at startup, and returns the
+ * appropriate BSP event.
+ *
+ * @param[out] p_startup_event Where to put the extracted BSP event.
+ */
+static void startup_event_extract(bsp_event_t * p_startup_event)
+{
+ // React to button states
+ if (bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE))
+ {
+ *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA;
+ }
+ else if (bsp_button_is_pressed(BTN_ID_WAKEUP))
+ {
+ *p_startup_event = BSP_EVENT_WAKEUP;
+ }
+ else
+ {
+ *p_startup_event = BSP_EVENT_NOTHING;
+ }
+}
+
+
+uint32_t bsp_btn_ble_sleep_mode_prepare(void)
+{
+ uint32_t err_code;
+
+ err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP);
+ RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
+
+ err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP_BOND_DELETE);
+ RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ if (m_num_connections == 0)
+ {
+ err_code = connection_buttons_configure();
+ CALL_HANDLER_ON_ERROR(err_code);
+ }
+
+ m_num_connections++;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_num_connections--;
+
+ if (m_num_connections == 0)
+ {
+ err_code = advertising_buttons_configure();
+ CALL_HANDLER_ON_ERROR(err_code);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+NRF_SDH_BLE_OBSERVER(m_ble_observer, BSP_BTN_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+
+uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ m_error_handler = error_handler;
+
+ if (p_startup_bsp_evt != NULL)
+ {
+ startup_event_extract(p_startup_bsp_evt);
+ }
+
+ if (m_num_connections == 0)
+ {
+ err_code = advertising_buttons_configure();
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h
new file mode 100644
index 0000000..5184b61
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup bsp_btn_ble BSP: BLE Button Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for controlling BLE behavior through button actions.
+ *
+ * @details The application must propagate BLE events to the BLE Button Module.
+ * Based on these events, the BLE Button Module configures the Board Support Package
+ * to generate BSP events for certain button actions. These BSP events should then be
+ * handled by the application's BSP event handler.
+ *
+ */
+
+#ifndef BSP_BTN_BLE_H__
+#define BSP_BTN_BLE_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "bsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BLE Button Module error handler type. */
+typedef void (*bsp_btn_ble_error_handler_t) (uint32_t nrf_error);
+
+/**@brief Function for initializing the BLE Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons.
+ *
+ * @param[out] error_handler Error handler to call in case of internal errors in BLE Button
+ * Module.
+ * @param[out] p_startup_bsp_evt If not a NULL pointer, the value is filled with an event
+ * (or BSP_EVENT_NOTHING) derived from the buttons pressed on
+ * startup. For example, if the bond delete wakeup button was pressed
+ * to wake up the device, *p_startup_bsp_evt is set to
+ * @ref BSP_EVENT_CLEAR_BONDING_DATA.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is
+ * returned.
+ */
+uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt);
+
+/**@brief Function for setting up wakeup buttons before going into sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error
+ * code is returned.
+ */
+uint32_t bsp_btn_ble_sleep_mode_prepare(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_BTN_BLE_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c
new file mode 100644
index 0000000..2389d84
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "bsp_cli.h"
+
+static bsp_event_callback_t m_bsp_cli_callback = NULL;
+
+static void cmd_btn(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t id;
+ ASSERT(m_bsp_cli_callback != NULL);
+
+ sscanf(argv[1], "%"SCNu32, &id);
+ bsp_event_t ev = (bsp_event_t)(BSP_EVENT_KEY_0 + id);
+ m_bsp_cli_callback(ev);
+}
+
+static void cmd_evt(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t id;
+ ASSERT(m_bsp_cli_callback != NULL);
+
+ sscanf(argv[1], "%"SCNu32, &id);
+ bsp_event_t ev = (bsp_event_t)id;
+ m_bsp_cli_callback(ev);
+}
+
+ret_code_t bsp_cli_init(bsp_event_callback_t callback)
+{
+ m_bsp_cli_callback = callback;
+
+ return NRF_SUCCESS;
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_bsp)
+{
+ NRF_CLI_CMD(btn, NULL, "BSP button event key", cmd_btn),
+ NRF_CLI_CMD(evt, NULL, "BSP event id", cmd_evt),
+ NRF_CLI_SUBCMD_SET_END
+};
+NRF_CLI_CMD_REGISTER(bsp, &m_sub_bsp, "bsp", NULL);
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h
new file mode 100644
index 0000000..8c71d6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup bsp_cli BSP over CLI Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for sending BSP events over CLI.
+ *
+ * @details The module uses Command Line Interface and enables user to send events
+ * to BSP. They are later handled by the event handler provided.
+ * Available commands:
+ * - bsp btn X (where X is button number) - sends BSP_EVENT_KEY_X
+ * - bsp evt X (where X is event number) - sends BSP event with X id
+ */
+
+#ifndef BSP_CLI_H__
+#define BSP_CLI_H__
+
+#include <stdint.h>
+#include "nrf_cli.h"
+#include "bsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for initializing the BSP over CLI Module.
+ *
+ * Before calling this function, the BSP module must be initialized.
+ *
+ * @param[in] callback Function to be called when event is recevied.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ */
+
+ret_code_t bsp_cli_init(bsp_event_callback_t callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_CLI_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h
new file mode 100644
index 0000000..343a0fe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup bsp Board Support Package
+ * @{
+ * @ingroup app_common
+ *
+ * @brief BSP module.
+ * @details This module provides a layer of abstraction from the board.
+ * It allows the user to indicate certain states on LEDs in a simple way.
+ * Module functionality can be modified by additional defines:
+ * - BSP_SIMPLE - reduces functionality of this module to enable
+ * and read state of the buttons.
+ * - BSP_UART_SUPPORT - enables support for UART.
+ */
+
+#ifndef BSP_CONFIG_H__
+#define BSP_CONFIG_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "boards.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE)
+#include "app_button.h"
+
+#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */
+#endif
+
+#define BSP_MS_TO_TICK(MS) (m_app_ticks_per_100ms * (MS / 100))
+
+
+#define BUTTON_ERASE_BONDING BSP_BUTTON_0_MASK
+#define BUTTON_ERASE_ALL BSP_BUTTON_1_MASK
+#define BUTTON_ADVERTISE BSP_BUTTON_0_MASK
+#define BUTTON_CLEAR_EVT BSP_BUTTON_1_MASK
+#define BUTTON_CAPSLOCK BSP_BUTTON_2_MASK
+#define BSP_BUTTONS_ALL 0xFFFFFFFF
+#define BSP_BUTTONS_NONE 0
+
+#define BSP_LONG_PUSH_TIMEOUT_MS (1000) /**< The time to hold for a long push (in milliseconds). */
+/**@brief Types of BSP initialization.
+ */
+
+#define ADVERTISING_LED_ON_INTERVAL 200
+#define ADVERTISING_LED_OFF_INTERVAL 1800
+
+#define ADVERTISING_DIRECTED_LED_ON_INTERVAL 200
+#define ADVERTISING_DIRECTED_LED_OFF_INTERVAL 200
+
+#define ADVERTISING_WHITELIST_LED_ON_INTERVAL 200
+#define ADVERTISING_WHITELIST_LED_OFF_INTERVAL 800
+
+#define ADVERTISING_SLOW_LED_ON_INTERVAL 400
+#define ADVERTISING_SLOW_LED_OFF_INTERVAL 4000
+
+#define BONDING_INTERVAL 100
+
+#define SENT_OK_INTERVAL 100
+#define SEND_ERROR_INTERVAL 500
+
+#define RCV_OK_INTERVAL 100
+#define RCV_ERROR_INTERVAL 500
+
+#define ALERT_INTERVAL 200
+
+#define BSP_LED_INDICATE_SENT_OK BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_SEND_ERROR BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_RCV_OK BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_RCV_ERROR BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_CONNECTED BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_BONDING BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_ADVERTISING_DIRECTED BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_ADVERTISING_SLOW BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_ADVERTISING_WHITELIST BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_INDICATE_ADVERTISING BSP_BOARD_LED_0
+
+#define BSP_LED_INDICATE_USER_LED1 BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_USER_LED2 BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_USER_LED3 BSP_BOARD_LED_2
+#define BSP_LED_INDICATE_USER_LED4 BSP_BOARD_LED_3
+
+#define BSP_LED_ALERT BSP_BOARD_LED_2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BSP_CONFIG_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c
new file mode 100644
index 0000000..50cc01c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "bsp_nfc.h"
+#include "bsp.h"
+#include "nrf.h"
+#include "app_util_platform.h"
+
+#ifndef BSP_SIMPLE
+#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */
+
+ret_code_t bsp_nfc_btn_init(uint32_t sleep_button)
+{
+ uint32_t err_code = bsp_event_to_button_action_assign(sleep_button,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_SLEEP);
+ return err_code;
+}
+
+ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button)
+{
+ uint32_t err_code = bsp_event_to_button_action_assign(sleep_button,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_DEFAULT);
+ return err_code;
+}
+
+ret_code_t bsp_nfc_sleep_mode_prepare(void)
+{
+#if defined(NFCT_PRESENT)
+ // Check if peripheral is not used.
+ CRITICAL_REGION_ENTER();
+#ifdef NRF52832_XXAA
+ if ((*(uint32_t *)0x40005410 & 0x07) == 0)
+#else
+ if ((NRF_NFCT->NFCTAGSTATE & NFCT_NFCTAGSTATE_NFCTAGSTATE_Msk)
+ == NFCT_NFCTAGSTATE_NFCTAGSTATE_Disabled)
+#endif // NRF52832_XXAA
+ {
+ NRF_NFCT->TASKS_SENSE = 1;
+ }
+ CRITICAL_REGION_EXIT();
+ return NRF_SUCCESS;
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+#endif //BSP_SIMPLE
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h
new file mode 100644
index 0000000..90a8cc9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup bsp_nfc NFC BSP Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for setting the NFCT peripheral as a wakeup source.
+ *
+ * @details The application must notify this module before going into System OFF mode.
+ * Based on this notification, the NFC BSP Module sets the NFCT peripheral as a wakeup source
+ * through the Board Support Package. Additionally, any BSP Button can be configured to
+ * generate BSP sleep events. This module is applicable only if NFCT is used exclusively for
+ * wakeup. If NFCT is used for a different purpose, this module cannot be used.
+ */
+
+#ifndef BSP_NFC_H__
+#define BSP_NFC_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for initializing the NFC Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons. The chosen
+ * button is used to generate @ref BSP_EVENT_SLEEP events.
+ *
+ * @param[in] sleep_button Button ID used to generate @ref BSP_EVENT_SLEEP event.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t bsp_nfc_btn_init(uint32_t sleep_button);
+
+/**@brief Function for deinitializing the NFC Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons. The chosen
+ * button is used to generate default @ref BSP_EVENT_DEFAULT events.
+ *
+ * @param[in] sleep_button Button ID used to restore default event generation.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button);
+
+/**@brief Function for setting up NFCT peripheral as wake-up source.
+ *
+ * This function must be called before going into System OFF mode.
+ *
+ * @note This function is only applicable if NFCT is used exclusively for wakeup.
+ * If NFCT is used for a different purpose, this function cannot be used.
+ *
+ * @retval NRF_SUCCESS If NFCT peripheral was prepared successfully. Otherwise,
+ * a propagated error code is returned.
+ */
+ret_code_t bsp_nfc_sleep_mode_prepare(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_NFC_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c
new file mode 100644
index 0000000..b422095
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BUTTON)
+#include "app_button.h"
+#include "app_timer.h"
+#include "app_error.h"
+#include "nrf_drv_gpiote.h"
+#include "nrf_assert.h"
+
+
+static app_button_cfg_t const * mp_buttons = NULL; /**< Button configuration. */
+static uint8_t m_button_count; /**< Number of configured buttons. */
+static uint32_t m_detection_delay; /**< Delay before a button is reported as pushed. */
+APP_TIMER_DEF(m_detection_delay_timer_id); /**< Polling timer id. */
+
+
+static uint64_t m_pin_state;
+static uint64_t m_pin_transition;
+
+/**@brief Function for handling the timeout that delays reporting buttons as pushed.
+ *
+ * @details The detection_delay_timeout_handler(...) is a call-back issued from the app_timer
+ * module. It is called with the p_context parameter. The p_context parameter is
+ * provided to the app_timer module when a timer is started, using the call
+ * @ref app_timer_start. On @ref app_timer_start the p_context will be holding the
+ * currently pressed buttons.
+ *
+ * @param[in] p_context Pointer used for passing information app_start_timer() was called.
+ * In the app_button module the p_context holds information on pressed
+ * buttons.
+ */
+static void detection_delay_timeout_handler(void * p_context)
+{
+ uint8_t i;
+
+ // Pushed button(s) detected, execute button handler(s).
+ for (i = 0; i < m_button_count; i++)
+ {
+ app_button_cfg_t const * p_btn = &mp_buttons[i];
+ uint64_t btn_mask = 1ULL << p_btn->pin_no;
+ if (btn_mask & m_pin_transition)
+ {
+ m_pin_transition &= ~btn_mask;
+ bool pin_is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
+ if ((m_pin_state & (1ULL << p_btn->pin_no)) == (((uint64_t)pin_is_set) << p_btn->pin_no))
+ {
+ uint32_t transition = !(pin_is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH));
+
+ if (p_btn->button_handler)
+ {
+ p_btn->button_handler(p_btn->pin_no, transition);
+ }
+ }
+ }
+ }
+}
+
+static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
+{
+ uint32_t err_code;
+ uint64_t pin_mask = 1ULL << pin;
+
+ // Start detection timer. If timer is already running, the detection period is restarted.
+ // NOTE: Using the p_context parameter of app_timer_start() to transfer the pin states to the
+ // timeout handler (by casting event_pins_mask into the equally sized void * p_context
+ // parameter).
+ err_code = app_timer_stop(m_detection_delay_timer_id);
+ if (err_code != NRF_SUCCESS)
+ {
+ // The impact in app_button of the app_timer queue running full is losing a button press.
+ // The current implementation ensures that the system will continue working as normal.
+ return;
+ }
+
+ if (!(m_pin_transition & pin_mask))
+ {
+ if (nrf_drv_gpiote_in_is_set(pin))
+ {
+ m_pin_state |= pin_mask;
+ }
+ else
+ {
+ m_pin_state &= ~(pin_mask);
+ }
+ m_pin_transition |= (pin_mask);
+
+ err_code = app_timer_start(m_detection_delay_timer_id, m_detection_delay, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ // The impact in app_button of the app_timer queue running full is losing a button press.
+ // The current implementation ensures that the system will continue working as normal.
+ }
+ }
+ else
+ {
+ m_pin_transition &= ~pin_mask;
+ }
+}
+
+uint32_t app_button_init(app_button_cfg_t const * p_buttons,
+ uint8_t button_count,
+ uint32_t detection_delay)
+{
+ uint32_t err_code;
+
+ if (detection_delay < APP_TIMER_MIN_TIMEOUT_TICKS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (!nrf_drv_gpiote_is_init())
+ {
+ err_code = nrf_drv_gpiote_init();
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Save configuration.
+ mp_buttons = p_buttons;
+ m_button_count = button_count;
+ m_detection_delay = detection_delay;
+
+ m_pin_state = 0;
+ m_pin_transition = 0;
+
+ while (button_count--)
+ {
+ app_button_cfg_t const * p_btn = &p_buttons[button_count];
+
+#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
+ nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(p_btn->hi_accuracy);
+#else
+ nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
+#endif
+ config.pull = p_btn->pull_cfg;
+
+ err_code = nrf_drv_gpiote_in_init(p_btn->pin_no, &config, gpiote_event_handler);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Create polling timer.
+ return app_timer_create(&m_detection_delay_timer_id,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ detection_delay_timeout_handler);
+}
+
+uint32_t app_button_enable(void)
+{
+ ASSERT(mp_buttons);
+
+ uint32_t i;
+ for (i = 0; i < m_button_count; i++)
+ {
+ nrf_drv_gpiote_in_event_enable(mp_buttons[i].pin_no, true);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_button_disable(void)
+{
+ ASSERT(mp_buttons);
+
+ uint32_t i;
+ for (i = 0; i < m_button_count; i++)
+ {
+ nrf_drv_gpiote_in_event_disable(mp_buttons[i].pin_no);
+ }
+
+ // Make sure polling timer is not running.
+ return app_timer_stop(m_detection_delay_timer_id);
+}
+
+
+bool app_button_is_pushed(uint8_t button_id)
+{
+ ASSERT(button_id <= m_button_count);
+ ASSERT(mp_buttons != NULL);
+
+ app_button_cfg_t const * p_btn = &mp_buttons[button_id];
+ bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
+
+ return !(is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH));
+}
+#endif //NRF_MODULE_ENABLED(BUTTON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h
new file mode 100644
index 0000000..3c1aa5a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup app_button Button Handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Buttons handling module.
+ *
+ * @details The button handler uses the @ref app_gpiote to detect that a button has been
+ * pushed. To handle debouncing, it will start a timer in the GPIOTE event handler.
+ * The button will only be reported as pushed if the corresponding pin is still active when
+ * the timer expires. If there is a new GPIOTE event while the timer is running, the timer
+ * is restarted.
+ *
+ * @note The app_button module uses the app_timer module. The user must ensure that the queue in
+ * app_timer is large enough to hold the app_timer_stop() / app_timer_start() operations
+ * which will be executed on each event from GPIOTE module (2 operations), as well as other
+ * app_timer operations queued simultaneously in the application.
+ *
+ * @note Even if the scheduler is not used, app_button.h will include app_scheduler.h, so when
+ * compiling, app_scheduler.h must be available in one of the compiler include paths.
+ */
+
+#ifndef APP_BUTTON_H__
+#define APP_BUTTON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "app_error.h"
+#include "nrf_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define APP_BUTTON_PUSH 1 /**< Indicates that a button is pushed. */
+#define APP_BUTTON_RELEASE 0 /**< Indicates that a button is released. */
+#define APP_BUTTON_ACTIVE_HIGH 1 /**< Indicates that a button is active high. */
+#define APP_BUTTON_ACTIVE_LOW 0 /**< Indicates that a button is active low. */
+
+/**@brief Button event handler type. */
+typedef void (*app_button_handler_t)(uint8_t pin_no, uint8_t button_action);
+
+/**@brief Button configuration structure. */
+typedef struct
+{
+ uint8_t pin_no; /**< Pin to be used as a button. */
+ uint8_t active_state; /**< APP_BUTTON_ACTIVE_HIGH or APP_BUTTON_ACTIVE_LOW. */
+#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
+ bool hi_accuracy; /**< True if GPIOTE high accuracy (IN_EVENT) is used. */
+#endif
+ nrf_gpio_pin_pull_t pull_cfg; /**< Pull-up or -down configuration. */
+ app_button_handler_t button_handler; /**< Handler to be called when button is pushed. */
+} app_button_cfg_t;
+
+/**@brief Function for initializing the Buttons.
+ *
+ * @details This function will initialize the specified pins as buttons, and configure the Button
+ * Handler module as a GPIOTE user (but it will not enable button detection).
+ *
+ * @note Normally initialization should be done using the APP_BUTTON_INIT() macro
+ *
+ * @note app_button_enable() function must be called in order to enable the button detection.
+ *
+ * @param[in] p_buttons Array of buttons to be used (NOTE: Must be static!).
+ * @param[in] button_count Number of buttons.
+ * @param[in] detection_delay Delay from a GPIOTE event until a button is reported as pushed.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t app_button_init(app_button_cfg_t const * p_buttons,
+ uint8_t button_count,
+ uint32_t detection_delay);
+
+/**@brief Function for enabling button detection.
+ *
+ * @retval NRF_SUCCESS Module successfully enabled.
+ */
+uint32_t app_button_enable(void);
+
+/**@brief Function for disabling button detection.
+ *
+ * @retval NRF_SUCCESS Button detection successfully disabled. Error code otherwise.
+ */
+uint32_t app_button_disable(void);
+
+/**@brief Function for checking if a button is currently being pushed.
+ *
+ * @param[in] button_id Button index (in the app_button_cfg_t array given to app_button_init) to be checked.
+ *
+ * @return Button state.
+ */
+bool app_button_is_pushed(uint8_t button_id);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_BUTTON_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c
new file mode 100644
index 0000000..e469853
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c
@@ -0,0 +1,317 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_BLE_UART)
+#include "nrf_cli_ble_uart.h"
+#include "ble_nus.h"
+#include "nrf_ringbuf.h"
+#include "app_timer.h"
+#include "nrf_assert.h"
+#include "nrf_ble_gatt.h"
+#define NRF_LOG_MODULE_NAME cli_ble
+
+#if NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_CLI_BLE_UART_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR
+
+#else //NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if NRF_CLI_BLE_UART_MAX_CLIENTS > NRF_SDH_BLE_TOTAL_LINK_COUNT
+ #error "Too few BLE peripheral links are supported by the BLE SDH module for the maximal number \
+ of BLE transport instances"
+#endif
+
+#define NRF_CLI_BLE_UART_TIMEOUT_MS 50
+#define OVERHEAD_LENGTH (OPCODE_LENGTH + HANDLE_LENGTH)
+
+BLE_NUS_DEF(m_nus, NRF_CLI_BLE_UART_MAX_CLIENTS);
+BLE_LINK_CTX_MANAGER_DEF(m_link_ctx_storage,
+ NRF_CLI_BLE_UART_MAX_CLIENTS,
+ sizeof(nrf_cli_ble_uart_internal_t *));
+
+static void tx_try(nrf_cli_ble_uart_internal_t * p_instance, uint32_t threshold)
+{
+ uint8_t * p_out_data;
+ size_t out_data_len =
+ nrf_ble_gatt_eff_mtu_get(p_instance->p_gatt, p_instance->p_cb->conn_handle) -
+ OVERHEAD_LENGTH;
+
+ ret_code_t err_code = nrf_ringbuf_get(p_instance->p_tx_ringbuf,
+ &p_out_data,
+ &out_data_len,
+ true);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (out_data_len >= threshold)
+ {
+ size_t req_data_len = out_data_len;
+ err_code = ble_nus_data_send(&m_nus,
+ p_out_data,
+ (uint16_t*)&out_data_len,
+ p_instance->p_cb->conn_handle);
+
+ if ((err_code == NRF_ERROR_BUSY) || (err_code == NRF_ERROR_RESOURCES))
+ {
+ out_data_len = 0;
+ }
+ NRF_LOG_INFO("Conn_handle:%d TX req_len: %d, len: %d",
+ p_instance->p_cb->conn_handle, req_data_len, out_data_len);
+ NRF_LOG_HEXDUMP_DEBUG(p_out_data, out_data_len);
+ err_code = nrf_ringbuf_free(p_instance->p_tx_ringbuf, out_data_len);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ else
+ {
+ err_code = nrf_ringbuf_free(p_instance->p_tx_ringbuf, 0);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ }
+}
+
+static void nus_data_handler(ble_nus_evt_t * p_nus_evt)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ nrf_cli_ble_uart_internal_t * p_instance;
+ nrf_cli_ble_uart_internal_t ** pp_instance;
+
+ err_code = blcm_link_ctx_get(&m_link_ctx_storage, p_nus_evt->conn_handle, (void *) &pp_instance);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ p_instance = *pp_instance;
+
+ switch (p_nus_evt->type)
+ {
+ case BLE_NUS_EVT_RX_DATA:
+ {
+ NRF_LOG_INFO("Conn_handle:%d, Received: %d",
+ p_instance->p_cb->conn_handle, p_nus_evt->params.rx_data.length);
+ NRF_LOG_HEXDUMP_DEBUG(p_nus_evt->params.rx_data.p_data, p_nus_evt->params.rx_data.length);
+ size_t len = ((size_t) p_nus_evt->params.rx_data.length) & 0x0000FFFF;
+ err_code = nrf_ringbuf_cpy_put(p_instance->p_rx_ringbuf,
+ p_nus_evt->params.rx_data.p_data,
+ (size_t *)&len);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, p_instance->p_cb->p_context);
+ break;
+ }
+ case BLE_NUS_EVT_TX_RDY:
+ {
+ //TX_Complete
+ uint32_t max_tx_len = nrf_ble_gatt_eff_mtu_get(p_instance->p_gatt,
+ p_instance->p_cb->conn_handle) -
+ OVERHEAD_LENGTH;
+ tx_try(p_instance, max_tx_len);
+ p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_instance->p_cb->p_context);
+ break;
+ }
+ case BLE_NUS_EVT_COMM_STARTED:
+ p_instance->p_cb->service_started = true;
+ err_code = app_timer_start(*p_instance->p_timer,
+ APP_TIMER_TICKS(NRF_CLI_BLE_UART_TIMEOUT_MS),
+ p_instance);
+ ASSERT(err_code == NRF_SUCCESS);
+ NRF_LOG_INFO("Conn_handle:%d, communication started", p_instance->p_cb->conn_handle);
+ break;
+ case BLE_NUS_EVT_COMM_STOPPED:
+ (void)app_timer_stop(*p_instance->p_timer);
+ p_instance->p_cb->service_started = false;
+ NRF_LOG_INFO("Conn_handle:%d, communication stopped", p_instance->p_cb->conn_handle);
+ break;
+ default:
+ break;
+ }
+}
+
+static void timer_handler(void * p_context)
+{
+ nrf_cli_ble_uart_internal_t * p_instance = (nrf_cli_ble_uart_internal_t *) p_context;
+ tx_try(p_instance, 1);
+
+ ret_code_t err_code = app_timer_start(*p_instance->p_timer,
+ APP_TIMER_TICKS(NRF_CLI_BLE_UART_TIMEOUT_MS), (void *)p_instance);
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_VARIABLE(err_code);
+ UNUSED_PARAMETER(p_context);
+}
+
+ret_code_t nrf_cli_ble_uart_service_init(void)
+{
+ ble_nus_init_t nus_init;
+
+ memset(&nus_init, 0, sizeof(nus_init));
+ nus_init.data_handler = nus_data_handler;
+
+ return ble_nus_init(&m_nus, &nus_init);
+}
+
+static ret_code_t cli_ble_uart_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ ret_code_t err_code;
+ nrf_cli_ble_uart_internal_t ** pp_instance;
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+ nrf_cli_ble_uart_config_t * p_ble_uart_config = (nrf_cli_ble_uart_config_t *)p_config;
+
+ p_instance->p_cb->handler = evt_handler;
+ p_instance->p_cb->p_context = p_context;
+ p_instance->p_cb->service_started = false;
+ p_instance->p_cb->conn_handle = p_ble_uart_config->conn_handle;
+
+ NRF_LOG_INFO("Conn_handle:%d init.", p_ble_uart_config->conn_handle);
+ nrf_ringbuf_init(p_instance->p_rx_ringbuf);
+ nrf_ringbuf_init(p_instance->p_tx_ringbuf);
+
+ err_code = blcm_link_ctx_get(&m_link_ctx_storage,
+ p_ble_uart_config->conn_handle,
+ (void *) &pp_instance);
+ VERIFY_SUCCESS(err_code);
+
+ *pp_instance = p_instance;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_ble_uart_uninit(nrf_cli_transport_t const * p_transport)
+{
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+
+ NRF_LOG_INFO("Conn_handle:%d uninit.", p_instance->p_cb->conn_handle);
+ ret_code_t ret = app_timer_stop(*p_instance->p_timer);
+
+ return ret;
+}
+
+static ret_code_t cli_ble_uart_enable(nrf_cli_transport_t const * p_transport, bool blocking)
+{
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+
+
+ NRF_LOG_INFO("Conn_handle:%d, enable blocking:%d", blocking, p_instance->p_cb->conn_handle);
+ if (blocking)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else
+ {
+ ret_code_t err_code = NRF_SUCCESS;
+ if (!p_instance->p_cb->timer_created)
+ {
+ err_code = app_timer_create(p_instance->p_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timer_handler);
+ p_instance->p_cb->timer_created = true;
+ }
+ return err_code;
+ }
+}
+
+static ret_code_t cli_ble_uart_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
+
+ if (*p_cnt)
+ {
+ NRF_LOG_INFO("Conn_handle:%d, read req_len:%d read_len: %d",
+ p_instance->p_cb->conn_handle,
+ length,
+ *p_cnt);
+ NRF_LOG_HEXDUMP_DEBUG(p_data, *p_cnt);
+ }
+
+ return err_code;
+}
+
+static ret_code_t cli_ble_uart_write(nrf_cli_transport_t const * p_transport,
+ const void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+ ret_code_t err_code = NRF_SUCCESS;
+ if (p_instance->p_cb->service_started)
+ {
+ *p_cnt = length;
+ err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
+
+ NRF_LOG_INFO("Conn_handle:%d, write req:%d, buffered:%d",
+ p_instance->p_cb->conn_handle, length, *p_cnt);
+ NRF_LOG_HEXDUMP_DEBUG(p_data, *p_cnt);
+ }
+ else
+ {
+ NRF_LOG_INFO("Conn_handle:%d, write req:%d. Notifications not enabled",
+ p_instance->p_cb->conn_handle, length);
+ *p_cnt = length;
+ p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_instance->p_cb->p_context);
+ }
+ return err_code;
+}
+
+const nrf_cli_transport_api_t nrf_cli_ble_uart_transport_api = {
+ .init = cli_ble_uart_init,
+ .uninit = cli_ble_uart_uninit,
+ .enable = cli_ble_uart_enable,
+ .read = cli_ble_uart_read,
+ .write = cli_ble_uart_write,
+};
+
+#endif //NRF_MODULE_ENABLED(NRF_CLI_BLE_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h
new file mode 100644
index 0000000..6111940
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_BLE_UART_H__
+#define NRF_CLI_BLE_UART_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_cli.h"
+#include "ble.h"
+#include "app_timer.h"
+#include "nrf_ringbuf.h"
+#include "nordic_common.h"
+#include "nrf_ble_gatt.h"
+/**@file
+ *
+ * @defgroup nrf_cli_ble_uart BLE UART command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+
+ret_code_t nrf_cli_ble_uart_service_init(void);
+
+extern const nrf_cli_transport_api_t nrf_cli_ble_uart_transport_api;
+
+typedef struct nrf_cli_ble_uart_internal_s nrf_cli_ble_uart_internal_t;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+ uint16_t conn_handle;
+ bool timer_created;
+ bool service_started;
+} nrf_cli_ble_uart_internal_cb_t;
+
+
+struct nrf_cli_ble_uart_internal_s {
+ nrf_cli_transport_t transport;
+ nrf_cli_ble_uart_internal_cb_t * p_cb;
+ app_timer_id_t const * p_timer;
+ nrf_ringbuf_t const * p_rx_ringbuf;
+ nrf_ringbuf_t const * p_tx_ringbuf;
+ nrf_ble_gatt_t const * p_gatt;
+};
+
+typedef struct {
+ uint16_t conn_handle;
+} nrf_cli_ble_uart_config_t;
+
+/**@brief CLI Bluetooth transport definition.
+ *
+ * @param _name Name of the instance.
+ * @param _p_gatt Pointer to the nrf_ble_gatt module.
+ * @param _tx_buf_sz Size of TX ring buffer.
+ * @param _rx_buf_sz Size of RX ring buffer.
+ */
+#define NRF_CLI_BLE_UART_DEF(_name, _p_gatt, _tx_buf_sz, _rx_buf_sz) \
+ APP_TIMER_DEF(CONCAT_2(_name, _timer)); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
+ static nrf_cli_ble_uart_internal_cb_t CONCAT_2(_name, _cb); \
+ static const nrf_cli_ble_uart_internal_t _name = { \
+ .transport = {.p_api = &nrf_cli_ble_uart_transport_api}, \
+ .p_cb = &CONCAT_2(_name, _cb), \
+ .p_timer = &CONCAT_2(_name, _timer), \
+ .p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
+ .p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
+ .p_gatt = _p_gatt, \
+ }
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_BLE_UART_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c
new file mode 100644
index 0000000..42adb75
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM)
+#include "nrf_cli_cdc_acm.h"
+#include "nrf_queue.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+
+
+#if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#error "Current CLI CDC implementation supports only USB with event queue disabled (see APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)"
+#endif
+
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+
+/*lint -save -e26 -e40 -e64 -e123 -e505 -e651*/
+
+/**
+ * @brief CDC_ACM class instance.
+ * */
+APP_USBD_CDC_ACM_GLOBAL_DEF(nrf_cli_cdc_acm,
+ cdc_acm_user_ev_handler,
+ NRF_CLI_CDC_ACM_COMM_INTERFACE,
+ NRF_CLI_CDC_ACM_DATA_INTERFACE,
+ NRF_CLI_CDC_ACM_COMM_EPIN,
+ NRF_CLI_CDC_ACM_DATA_EPIN,
+ NRF_CLI_CDC_ACM_DATA_EPOUT,
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250
+);
+
+/*lint -restore*/
+
+NRF_QUEUE_DEF(uint8_t,
+ m_rx_queue,
+ 2*NRF_DRV_USBD_EPSIZE,
+ NRF_QUEUE_MODE_OVERFLOW);
+
+static char m_rx_buffer[NRF_DRV_USBD_EPSIZE];
+
+static nrf_cli_cdc_acm_internal_t * mp_internal;
+
+/**
+ * @brief Set new buffer and process any data if already present
+ *
+ * This is internal function.
+ * The result of its execution is the library waiting for the event of the new data.
+ * If there is already any data that was returned from the CDC internal buffer
+ * it would be processed here.
+ */
+static void cdc_acm_process_and_prepare_buffer(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ for (;;)
+ {
+ if (!nrf_queue_is_empty(&m_rx_queue))
+ {
+ mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, mp_internal->p_cb->p_context);
+ }
+ ret_code_t ret = app_usbd_cdc_acm_read_any(&nrf_cli_cdc_acm,
+ m_rx_buffer,
+ sizeof(m_rx_buffer));
+ if (ret == NRF_SUCCESS)
+ {
+ size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
+ size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size);
+ ASSERT(size == qsize);
+ UNUSED_VARIABLE(qsize);
+ }
+ else if (ret == NRF_ERROR_IO_PENDING)
+ {
+ break;
+ }
+ else
+ {
+ APP_ERROR_CHECK(ret);
+ break;
+ }
+ }
+}
+
+/**
+ * @brief User event handler.
+ * */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
+
+
+ switch (event)
+ {
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+ {
+ /*Setup first transfer*/
+ cdc_acm_process_and_prepare_buffer(p_cdc_acm);
+ break;
+ }
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
+ break;
+ case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
+ mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, mp_internal->p_cb->p_context);
+ break;
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+ {
+ /*Get amount of data transfered*/
+ size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
+ size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size);
+ ASSERT(size == qsize);
+ UNUSED_VARIABLE(qsize);
+
+ /*Setup next transfer*/
+ cdc_acm_process_and_prepare_buffer(p_cdc_acm);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static ret_code_t cli_cdc_acm_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ UNUSED_PARAMETER(p_config);
+ nrf_cli_cdc_acm_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_cdc_acm_internal_t, transport);
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+
+ mp_internal = p_internal;
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_cdc_acm_uninit(nrf_cli_transport_t const * p_transport)
+{
+ UNUSED_PARAMETER(p_transport);
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_cdc_acm_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ UNUSED_PARAMETER(p_transport);
+ if (blocking)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+static ret_code_t cli_cdc_acm_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+ size_t size = nrf_queue_out(&m_rx_queue, p_data, length);
+ *p_cnt = size;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_cdc_acm_write(nrf_cli_transport_t const * p_transport,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+ ret_code_t ret;
+
+ ret = app_usbd_cdc_acm_write(&nrf_cli_cdc_acm, p_data, length);
+ if (ret == NRF_SUCCESS || ret == NRF_ERROR_INVALID_STATE)
+ {
+ *p_cnt = length;
+ ret = NRF_SUCCESS;
+ }
+ else if (ret == NRF_ERROR_BUSY)
+ {
+ *p_cnt = 0;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ return ret;
+}
+
+const nrf_cli_transport_api_t nrf_cli_cdc_acm_transport_api = {
+ .init = cli_cdc_acm_init,
+ .uninit = cli_cdc_acm_uninit,
+ .enable = cli_cdc_acm_enable,
+ .read = cli_cdc_acm_read,
+ .write = cli_cdc_acm_write,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h
new file mode 100644
index 0000000..a6d8829
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_CDC_ACM_H__
+#define NRF_CLI_CDC_ACM_H__
+
+#include <stdbool.h>
+
+#include "nrf_cli.h"
+#include "app_usbd_cdc_acm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_cli_cdc_acm CDC ACM command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+extern const nrf_cli_transport_api_t nrf_cli_cdc_acm_transport_api;
+
+/**
+ * @brief Command line interface class instance.
+ */
+extern const app_usbd_cdc_acm_t nrf_cli_cdc_acm;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+} nrf_cli_cdc_acm_internal_cb_t;
+
+typedef struct {
+ nrf_cli_transport_t transport;
+ nrf_cli_cdc_acm_internal_cb_t * p_cb;
+} nrf_cli_cdc_acm_internal_t;
+
+/**@brief CLI USB transport definition */
+#define NRF_CLI_CDC_ACM_DEF(_name_) \
+ static nrf_cli_cdc_acm_internal_cb_t CONCAT_2(_name_, _cb); \
+ static const nrf_cli_cdc_acm_internal_t _name_ = { \
+ .transport = {.p_api = &nrf_cli_cdc_acm_transport_api}, \
+ .p_cb = &CONCAT_2(_name_, _cb), \
+ }
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_CDC_ACM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c
new file mode 100644
index 0000000..9c0805d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_cli.h"
+#include "nrf_log.h"
+
+static void cmd_reset(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ NVIC_SystemReset();
+}
+
+
+static void cmd_error(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+}
+
+
+static void cmd_app_size(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Application address:%d (0x%08X), size: %d (0x%08X)\r\n",
+ CODE_START,
+ CODE_START,
+ CODE_SIZE,
+ CODE_SIZE);
+}
+
+
+static void cmd_log_msg_error(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ switch (argc-1)
+ {
+ case 0:
+ NRF_LOG_ERROR("test error message");
+ break;
+ case 1:
+ NRF_LOG_ERROR("test error message: %d", strtol(argv[1], NULL, 10));
+ break;
+ case 2:
+ NRF_LOG_ERROR("test error message: %d %d", strtol(argv[1], NULL, 10),
+ strtol(argv[2], NULL, 10));
+ break;
+ default:
+ NRF_LOG_ERROR("test error message with more than 3 arguments");
+ break;
+ }
+}
+
+
+static void cmd_log_msg_warning(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ switch (argc-1)
+ {
+ case 0:
+ NRF_LOG_WARNING("test warning message");
+ break;
+ case 1:
+ NRF_LOG_WARNING("test warning message: %d", strtol(argv[1], NULL, 10));
+ break;
+ case 2:
+ NRF_LOG_WARNING("test warning message: %d %d", strtol(argv[1], NULL, 10),
+ strtol(argv[2], NULL, 10));
+ break;
+ default:
+ NRF_LOG_WARNING("test warning message with more than 3 arguments");
+ break;
+ }
+}
+
+/**
+ * @brief Command set array
+ * */
+
+NRF_CLI_CMD_REGISTER(reset, NULL, "System reset.", cmd_reset);
+
+NRF_CLI_CMD_REGISTER(error, NULL, "Trigger error.", cmd_error);
+
+NRF_CLI_CMD_REGISTER(app_size, NULL, "Print application size.", cmd_app_size);
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_log_msg)
+{
+ NRF_CLI_CMD(error, NULL, "Error log message with parameters", cmd_log_msg_error),
+ NRF_CLI_CMD(warning, NULL, "Warning log message with parameters", cmd_log_msg_warning),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(log_msg, &m_sub_log_msg, "Trigger log message with decimal arguments", NULL);
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c
new file mode 100644
index 0000000..d64e141
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c
@@ -0,0 +1,247 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#include "nrf_cli_libuarte.h"
+#include "nrf_libuarte_async.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME cli_libuarte
+#if NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR
+#else //NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static cli_libuarte_internal_t * mp_internal;
+static bool m_uart_busy;
+
+static void uart_event_handler(nrf_libuarte_async_evt_t * p_event)
+{
+ cli_libuarte_internal_t * p_internal = mp_internal;
+ ret_code_t err_code = NRF_SUCCESS;
+ size_t len;
+ UNUSED_VARIABLE(err_code);
+ switch (p_event->type)
+ {
+ case NRF_LIBUARTE_ASYNC_EVT_ERROR:
+ NRF_LOG_WARNING("(evt) ERROR");
+
+ break;
+
+ case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
+ {
+ len = (size_t)((uint32_t)p_event->data.rxtx.length & 0x0000FFFF);
+ err_code = nrf_ringbuf_cpy_put(p_internal->p_rx_ringbuf,
+ p_event->data.rxtx.p_data,
+ &len);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if (len != p_event->data.rxtx.length)
+ {
+ NRF_LOG_WARNING("Data lost, no room in RX ringbuf");
+ }
+ nrf_libuarte_async_rx_free(p_event->data.rxtx.p_data, p_event->data.rxtx.length);
+
+ if (p_event->data.rxtx.length)
+ {
+ NRF_LOG_DEBUG("(evt) RXRDY length:%d", p_event->data.rxtx.length);
+ NRF_LOG_HEXDUMP_DEBUG(p_event->data.rxtx.p_data, p_event->data.rxtx.length);
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY,
+ p_internal->p_cb->p_context);
+ }
+
+ break;
+ }
+
+ case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
+ err_code = nrf_ringbuf_free(p_internal->p_tx_ringbuf, p_event->data.rxtx.length);
+ ASSERT(err_code == NRF_SUCCESS);
+ uint8_t * p_data;
+ len = 255;
+ err_code = nrf_ringbuf_get(p_internal->p_tx_ringbuf, &p_data, &len, true);
+ ASSERT(err_code == NRF_SUCCESS);
+ if (len)
+ {
+ NRF_LOG_DEBUG("(evt) Started TX (%d).", len);
+ err_code = nrf_libuarte_async_tx(p_data, len);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ else
+ {
+ m_uart_busy = false;
+ }
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
+ NRF_LOG_DEBUG("(evt) TX completed (%d)", p_event->data.rxtx.length);
+ break;
+
+ default:
+ NRF_LOG_ERROR("(evt) Unknown event");
+ ASSERT(false);
+ break;
+ }
+}
+
+static ret_code_t cli_libuarte_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ cli_libuarte_internal_t * p_internal = CONTAINER_OF(p_transport,
+ cli_libuarte_internal_t,
+ transport);
+ mp_internal = p_internal;
+ m_uart_busy = false;
+
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+ p_internal->p_cb->blocking = false;
+
+ cli_libuarte_config_t const * p_cli_libuarte_config = (cli_libuarte_config_t *)p_config;
+ nrf_libuarte_async_config_t uart_async_config = {
+ .tx_pin = p_cli_libuarte_config->tx_pin,
+ .rx_pin = p_cli_libuarte_config->rx_pin,
+ .baudrate = p_cli_libuarte_config->baudrate,
+ .parity = p_cli_libuarte_config->parity,
+ .hwfc = p_cli_libuarte_config->hwfc,
+ .timeout_us = 100,
+ };
+ ret_code_t err_code = nrf_libuarte_async_init(&uart_async_config, uart_event_handler);
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_ringbuf_init(p_internal->p_rx_ringbuf);
+ nrf_ringbuf_init(p_internal->p_tx_ringbuf);
+ }
+ return err_code;
+}
+
+static ret_code_t cli_libuarte_uninit(nrf_cli_transport_t const * p_transport)
+{
+ UNUSED_PARAMETER(p_transport);
+ nrf_libuarte_async_uninit();
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_libuarte_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ UNUSED_PARAMETER(p_transport);
+ if (blocking)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else
+ {
+ nrf_libuarte_async_enable(255);
+ }
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_libuarte_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ cli_libuarte_internal_t * p_instance =
+ CONTAINER_OF(p_transport, cli_libuarte_internal_t, transport);
+
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
+
+ if (*p_cnt)
+ {
+ NRF_LOG_DEBUG("Read %d bytes (requested %d)", *p_cnt, length);
+ }
+
+ return err_code;
+}
+
+static ret_code_t cli_libuarte_write(nrf_cli_transport_t const * p_transport,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ cli_libuarte_internal_t * p_instance = CONTAINER_OF(p_transport,
+ cli_libuarte_internal_t,
+ transport);
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Requested write: %d, copied to ringbuf: %d.", length, *p_cnt);
+
+ if (m_uart_busy)
+ {
+ return err_code;
+ }
+
+ uint8_t * p_buf;
+ size_t len = 255;
+ if (nrf_ringbuf_get(p_instance->p_tx_ringbuf, &p_buf, &len, true) == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Started TX (%d).", len);
+
+ err_code = nrf_libuarte_async_tx(p_buf, len);
+ if (p_instance->p_cb->blocking && (err_code == NRF_SUCCESS))
+ {
+ (void)nrf_ringbuf_free(p_instance->p_tx_ringbuf, len);
+ }
+ else
+ {
+ m_uart_busy = true;
+ }
+ }
+ }
+ return err_code;
+}
+
+const nrf_cli_transport_api_t cli_libuarte_transport_api = {
+ .init = cli_libuarte_init,
+ .uninit = cli_libuarte_uninit,
+ .enable = cli_libuarte_enable,
+ .read = cli_libuarte_read,
+ .write = cli_libuarte_write,
+};
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h
new file mode 100644
index 0000000..e37fe64
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_BACKEND_LIBUARTE_H__
+#define NRF_LOG_BACKEND_LIBUARTE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_cli.h"
+#include "nrf_libuarte.h"
+#include "nrf_ringbuf.h"
+#include "app_timer.h"
+
+/**@file
+ *
+ * @defgroup nrf_cli_libuarte libUARTE command line interface transport layer.
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ * */
+extern const nrf_cli_transport_api_t cli_libuarte_transport_api;
+
+typedef struct cli_libuarte_internal_s cli_libuarte_internal_t;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+ bool blocking;
+} cli_libuarte_internal_cb_t;
+
+struct cli_libuarte_internal_s {
+ nrf_cli_transport_t transport;
+ cli_libuarte_internal_cb_t * p_cb;
+ nrf_ringbuf_t const * p_rx_ringbuf;
+ nrf_ringbuf_t const * p_tx_ringbuf;
+};
+
+typedef struct
+{
+ uint32_t tx_pin;
+ uint32_t rx_pin;
+ nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uarte_parity_t parity; ///< Parity configuration.
+ nrf_uarte_baudrate_t baudrate; ///< Baudrate.
+} cli_libuarte_config_t;
+
+/**@brief CLI libUARTE transport definition.
+ *
+ * @param _name Name of instance.
+ * @param _tx_buf_sz Size of TX ring buffer.
+ * @param _rx_buf_sz Size of RX ring buffer.
+ */
+#define NRF_CLI_LIBUARTE_DEF(_name, _tx_buf_sz, _rx_buf_sz) \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
+ static cli_libuarte_internal_cb_t CONCAT_2(_name, _cb); \
+ static const cli_libuarte_internal_t _name = { \
+ .transport = {.p_api = &cli_libuarte_transport_api}, \
+ .p_cb = &CONCAT_2(_name, _cb), \
+ .p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
+ .p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
+ }
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_LOG_BACKEND_LIBUARTE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c
new file mode 100644
index 0000000..1e4eba5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c
@@ -0,0 +1,3500 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI)
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "nrf_cli.h"
+#include "nrf_cli_vt100.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+#include "nrf_delay.h"
+#include "nrf_pwr_mgmt.h"
+#include "nrf_atomic.h"
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+#include "fnmatch.h"
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ #if NRF_CLI_HISTORY_ELEMENT_SIZE * NRF_CLI_HISTORY_ELEMENT_COUNT == 0
+ #error Not proper memory size allocated for NRF_CLI_HISTORY
+ #endif
+#endif
+
+/* 2 == 1 char for cmd + 1 char for '\0' */
+#if NRF_CLI_CMD_BUFF_SIZE < 2
+ #error too small NRF_CLI_CMD_BUFF_SIZE
+#endif
+
+#if NRF_CLI_PRINTF_BUFF_SIZE < 1
+ #error too small NRF_CLI_PRINTF_BUFF_SIZE
+#endif
+
+#define NRF_CLI_HELP_CLEAR "Clear screen."
+#define NRF_CLI_HELP_COLORS "Toggle colored syntax."
+#define NRF_CLI_HELP_COLORS_OFF "Disable colored syntax."
+#define NRF_CLI_HELP_COLORS_ON "Enable colored syntax."
+#define NRF_CLI_HELP_STATISTICS "CLI statistics."
+#define NRF_CLI_HELP_STATISTICS_SHOW "Get CLI statistics for the Logger module."
+#define NRF_CLI_HELP_STATISTICS_RESET "Reset CLI statistics for the Logger module."
+#define NRF_CLI_HELP_RESIZE "Console gets terminal screen size or assumes 80 in case " \
+ "the readout fails. It must be executed after each terminal " \
+ "width change to ensure correct text display."
+#define NRF_CLI_HELP_RESIZE_DEFAULT "Assume 80 chars screen width and send this setting " \
+ "to the terminal."
+#define NRF_CLI_HELP_HISTORY "Command history."
+#define NRF_CLI_HELP_ECHO "Toggle CLI echo."
+#define NRF_CLI_HELP_ECHO_ON "Enable CLI echo."
+#define NRF_CLI_HELP_ECHO_OFF "Disable CLI echo. Arrows and buttons: Backspace, " \
+ "Delete, End, Home, Insert are not handled."
+#define NRF_CLI_HELP_CLI "Useful, not Unix-like CLI commands."
+
+#define NRF_CLI_MSG_SPECIFY_SUBCOMMAND "Please specify a subcommand.\r\n"
+#define NRF_CLI_MSG_UNKNOWN_PARAMETER " unknown parameter: "
+#define NRF_CLI_MSG_COMMAND_NOT_FOUND ": command not found"
+#define NRF_CLI_MSG_TAB_OVERFLOWED "Tab function: commands counter overflowed.\r\n"
+
+/*lint -save -esym(526,cli_command*) -esym(526,cli_sorted_cmd_ptrs*)*/
+NRF_SECTION_DEF(cli_command, nrf_cli_cmd_entry_t);
+#define CLI_DATA_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(cli_command, nrf_cli_cmd_entry_t, (i))
+#define CLI_DATA_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(cli_command, nrf_cli_cmd_entry_t)
+
+NRF_SECTION_DEF(cli_sorted_cmd_ptrs, const char *);
+/*lint -restore*/
+#define CLI_SORTED_CMD_PTRS_ITEM_GET(i) NRF_SECTION_ITEM_GET(cli_sorted_cmd_ptrs, const char *, (i))
+#define CLI_SORTED_CMD_PTRS_START_ADDR_GET NRF_SECTION_START_ADDR(cli_sorted_cmd_ptrs)
+
+#if defined(NRF_CLI_LOG_BACKEND) && NRF_CLI_LOG_BACKEND
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#endif
+
+#define NRF_CLI_INIT_OPTION_PRINTER (NULL)
+
+#define NRF_CLI_MAX_TERMINAL_SIZE (250u)
+#define NRF_CLI_CURSOR_POSITION_BUFFER (10u) /* 10 == {esc, [, 2, 5, 0, ;, 2, 5, 0, '\0'} */
+#define NRF_CLI_DEFAULT_TERMINAL_WIDTH (80u) /* Default PuTTY width. */
+#define NRF_CLI_DEFAULT_TERMINAL_HEIGHT (24u) /* Default PuTTY height. */
+#define NRF_CLI_INITIAL_CURS_POS (1u) /* Initial cursor position is: (1, 1). */
+
+#define NRF_CLI_CMD_ROOT_LVL (0u)
+
+/* Macro to send VT100 commands. */
+#define NRF_CLI_VT100_CMD(_p_cli_, _cmd_) { \
+ ASSERT(_p_cli_); \
+ ASSERT(_p_cli_->p_fprintf_ctx); \
+ static char const cmd[] = _cmd_; \
+ nrf_fprintf(_p_cli_->p_fprintf_ctx, "%s", cmd); \
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+typedef enum
+{
+ WILDCARD_CMD_ADDED,
+ WILDCARD_CMD_ADDED_MISSING_SPACE,
+ WILDCARD_CMD_NO_MATCH_FOUND
+} wildcard_cmd_status_t;
+#endif
+
+
+static bool cli_log_entry_process(nrf_cli_t const * p_cli, bool skip);
+static void cli_execute(nrf_cli_t const * p_cli);
+
+
+static inline void transport_buffer_flush(nrf_cli_t const * p_cli)
+{
+ nrf_fprintf_buffer_flush(p_cli->p_fprintf_ctx);
+}
+
+static inline void cli_flag_help_set(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.show_help = 1;
+}
+static inline void cli_flag_help_clear(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.show_help = 0;
+}
+
+static inline void cli_flag_echo_set(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.echo = 1;
+}
+
+static inline void cli_flag_echo_clear(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.echo = 0;
+}
+
+static inline bool cli_flag_echo_is_set(nrf_cli_t const * p_cli)
+{
+ return p_cli->p_ctx->internal.flag.echo == 1 ? true : false;
+}
+
+static inline bool cli_flag_processing_is_set(nrf_cli_t const * p_cli)
+{
+ return p_cli->p_ctx->internal.flag.processing == 1 ? true : false;
+}
+
+static inline void recieve_state_change(nrf_cli_t const * p_cli, nrf_cli_receive_t state)
+{
+ p_cli->p_ctx->receive_state = state;
+}
+
+static inline size_t cli_strlen(char const * str)
+{
+ return str == NULL ? 0 : strlen(str);
+}
+
+/* Function returns true if cursor is at beginning of an empty line. */
+static inline bool cursor_in_empty_line(nrf_cli_t const * p_cli)
+{
+ return ( (p_cli->p_ctx->cmd_buff_pos + cli_strlen(p_cli->p_name)) %
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid == 0);
+}
+
+/* Function returns true if command length is equal to multiplicity of terminal width. */
+static inline bool full_line_cmd(nrf_cli_t const * p_cli)
+{
+ return ((p_cli->p_ctx->cmd_buff_len + cli_strlen(p_cli->p_name)) %
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid == 0);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+/* Function returns true if string contains wildcard character: '?' or '*'. */
+static bool wildcard_character_exist(char * p_str)
+{
+ size_t str_len = cli_strlen(p_str);
+ for (size_t i = 0; i < str_len; i++)
+ {
+ if ((p_str[i] == '?') || (p_str[i] == '*'))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
+/* Function sends data stream to the CLI instance. Each time before the cli_write function is called,
+ * it must be ensured that IO buffer of fprintf is flushed to avoid synchronization issues.
+ * For that purpose, use function transport_buffer_flush(p_cli) */
+static void cli_write(nrf_cli_t const * p_cli,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cli && p_data);
+ ASSERT(p_cli->p_iface->p_api);
+ size_t offset = 0;
+ size_t cnt;
+ while (length)
+ {
+ ret_code_t ret = p_cli->p_iface->p_api->write(p_cli->p_iface,
+ &((uint8_t const *)p_data)[offset],
+ length,
+ &cnt);
+ UNUSED_VARIABLE(ret);
+ ASSERT(ret == NRF_SUCCESS);
+ ASSERT(length >= cnt);
+ offset += cnt;
+ length -= cnt;
+ if (cnt == 0 && (p_cli->p_ctx->state != NRF_CLI_STATE_PANIC_MODE_ACTIVE))
+ {
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ (void)task_events_wait(NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT);
+#else
+ while (p_cli->p_ctx->internal.flag.tx_rdy == 0)
+ {
+ ;
+ }
+ p_cli->p_ctx->internal.flag.tx_rdy = 0;
+#endif
+ }
+ }
+
+ if (p_cnt)
+ {
+ *p_cnt = cnt;
+ }
+}
+
+/* Function sends 1 character to the CLI instance. */
+static inline void cli_putc(nrf_cli_t const * p_cli, char ch)
+{
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%c", ch);
+}
+
+/* Function reads data from the CLI instance. */
+static void cli_read(nrf_cli_t const * p_cli,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cli && p_data);
+ ASSERT(p_cli->p_iface);
+
+ ret_code_t ret = p_cli->p_iface->p_api->read(p_cli->p_iface, p_data, length, p_cnt);
+ UNUSED_VARIABLE(ret);
+}
+
+/* Function cmd_get shall be used to search commands. It moves the pointer pp_entry to command
+ * of static command structure. If the command cannot be found, the function will set pp_entry to NULL.
+ * p_command Pointer to command which will be processed (no matter the root command).
+ * lvl Level of the requested command.
+ * idx Index of the requested command.
+ * pp_entry Pointer which points to subcommand[idx] after function execution.
+ * p_st_entry Pointer to the structure where dynamic entry data can be stored.
+ */
+static void cmd_get(nrf_cli_cmd_entry_t const * p_command,
+ size_t lvl,
+ size_t idx,
+ nrf_cli_static_entry_t const ** pp_entry,
+ nrf_cli_static_entry_t * p_st_entry)
+{
+ ASSERT (pp_entry != NULL);
+ ASSERT (p_st_entry != NULL);
+
+ if (lvl == NRF_CLI_CMD_ROOT_LVL)
+ {
+ if (idx < CLI_DATA_SECTION_ITEM_COUNT)
+ {
+ nrf_cli_cmd_entry_t const * p_cmd = NULL;
+ char const * * pp_sorted_cmds = (char const * *)CLI_SORTED_CMD_PTRS_START_ADDR_GET;
+ for (size_t i = 0; i < CLI_DATA_SECTION_ITEM_COUNT; i++)
+ {
+ p_cmd = CLI_DATA_SECTION_ITEM_GET(i);
+ if (!strcmp(pp_sorted_cmds[idx], p_cmd->u.p_static->p_syntax))
+ {
+ *pp_entry = p_cmd->u.p_static;
+ return;
+ }
+ }
+ }
+ *pp_entry = NULL;
+ return;
+ }
+
+ if (p_command == NULL)
+ {
+ *pp_entry = NULL;
+ return;
+ }
+
+ if (p_command->is_dynamic)
+ {
+ p_command->u.p_dynamic_get(idx, p_st_entry);
+ if (p_st_entry->p_syntax == NULL)
+ {
+ *pp_entry = NULL;
+ }
+ else
+ {
+ *pp_entry = p_st_entry;
+ }
+ }
+ else
+ {
+ if (p_command->u.p_static[idx].p_syntax != NULL)
+ {
+ *pp_entry = &p_command->u.p_static[idx];
+ }
+ else
+ {
+ *pp_entry = NULL;
+ }
+ }
+}
+
+/* Function multiline_console_data_check checks the current cursor position (x, y) on terminal screen
+ * based on: command length, console name length, and terminal width.
+ * Example 1:
+ * || - cursor
+ * ----------------------------
+ * |console_name $: || |
+ * ----------------------------
+ * => coordinates are: cur_x = 17, cur_x_end = 17,
+ * cur_y = 1, cur_y_end = 1
+ * Example 2:
+ * ----------------------------
+ * |console_name $: test command|
+ * |showing |e|xample |
+ * ----------------------------
+ * => coordinates are: cur_x = 9, cur_x_end = 18 (cursor can be one column after 'e')
+ * => cur_y = 2, cur_y_end = 2
+ * Example 3:
+ * ----------------------------
+ * |console_name $: test command|
+ * |showing e|x|ample with more |
+ * |parameters |
+ * ----------------------------
+ * => coordinates are: cur_x = 10, cur_x_end = 11 (cursor can be one column after 's')
+ * => cur_y = 2, cur_y_end = 3
+ */
+static nrf_cli_multiline_cons_t const * multiline_console_data_check(nrf_cli_t const * p_cli)
+{
+ nrf_cli_ctx_t * p_ctx = p_cli->p_ctx;
+ nrf_cli_multiline_cons_t * p_cons = &p_cli->p_ctx->vt100_ctx.cons;
+
+ p_cons->name_len = cli_strlen(p_cli->p_name);
+
+ /* Current cursor position in command.
+ * +1 -> because home position is (1, 1) */
+ p_cons->cur_x = (p_ctx->cmd_buff_pos + p_cons->name_len) % p_cons->terminal_wid + 1;
+ p_cons->cur_y = (p_ctx->cmd_buff_pos + p_cons->name_len) / p_cons->terminal_wid + 1;
+
+ /* Extreme position when cursor is at the end of command. */
+ p_cons->cur_y_end = (p_ctx->cmd_buff_len + p_cons->name_len) / p_cons->terminal_wid + 1;
+ p_cons->cur_x_end = (p_ctx->cmd_buff_len + p_cons->name_len) % p_cons->terminal_wid + 1;
+
+ return p_cons;
+}
+
+/* Function sends VT100 command to clear the screen from cursor position to end of the screen. */
+static inline void cli_clear_eos(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEAREOS);
+}
+
+/* Function sends VT100 command to save cursor position. */
+static inline void cli_cursor_save(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_SAVECURSOR);
+}
+
+/* Function sends VT100 command to restore saved cursor position. */
+static inline void cli_cursor_restore(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_RESTORECURSOR);
+}
+
+/* Function forcing new line - cannot be replaced with function cursor_down_move. */
+static inline void cursor_next_line_move(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_NEXTLINE);
+}
+
+/* Function moves cursor left by n positions. */
+static inline void cursor_left_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dD", n);
+ }
+}
+
+/* Function moves cursor right by n positions. */
+static inline void cursor_right_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dC", n);
+ }
+}
+
+/* Function moves cursor up by n positions. */
+static inline void cursor_up_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dA", n);
+ }
+}
+
+/* Function moves cursor down by n positions but it will bring no effect if cursor is in the last
+ * line of terminal screen. In such case, the cursor_next_line_move function shall be invoked. */
+static inline void cursor_down_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dB", n);
+ }
+}
+
+/* Function increments cursor position (if possible) and moves cursor to new line if necessary. */
+static void cursor_position_increment(nrf_cli_t const * p_cli)
+{
+ if (p_cli->p_ctx->cmd_buff_pos >= p_cli->p_ctx->cmd_buff_len)
+ {
+ return; /* incrementation not possible */
+ }
+
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ nrf_cli_cmd_len_t cur_y = p_cons->cur_y;
+ ++p_cli->p_ctx->cmd_buff_pos;
+ p_cons = multiline_console_data_check(p_cli);
+
+ if (cur_y == p_cons->cur_y)
+ {
+ cursor_right_move(p_cli, 1);
+ }
+ else
+ {
+ cursor_next_line_move(p_cli);
+ }
+}
+
+/* Function will move cursor back to position == cmd_buff_pos. Example usage is when cursor needs
+ * to be moved back after printing some text. This function cannot be used to move cursor to new
+ * location by manual change of cmd_buff_pos.*/
+static void cursor_position_synchronize(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ /* In case cursor reaches the bottom line of a terminal, it will be moved to the next line. */
+ if (cursor_in_empty_line(p_cli) || full_line_cmd(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+
+ if (last_line)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x_end - p_cons->cur_x);
+ }
+ else
+ {
+ cursor_up_move(p_cli, p_cons->cur_y_end - p_cons->cur_y);
+ if (p_cons->cur_x > p_cons->cur_x_end)
+ {
+ cursor_right_move(p_cli, p_cons->cur_x - p_cons->cur_x_end);
+ }
+ else
+ {
+ cursor_left_move(p_cli, p_cons->cur_x_end - p_cons->cur_x);
+ }
+ }
+}
+
+/* Function moves cursor to begin of command position, just after console name. */
+static void cursor_home_position_move(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->name_len + NRF_CLI_INITIAL_CURS_POS) &&
+ (p_cons->cur_y == NRF_CLI_INITIAL_CURS_POS))
+ {
+ return; /* nothing to handle because cursor is in start position */
+ }
+
+ if (p_cons->cur_y > NRF_CLI_INITIAL_CURS_POS)
+ {
+ cursor_up_move(p_cli, p_cons->cur_y - NRF_CLI_INITIAL_CURS_POS);
+ }
+
+ if (p_cons->cur_x > p_cons->name_len)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x - NRF_CLI_INITIAL_CURS_POS - p_cons->name_len);
+ }
+ else
+ {
+ cursor_right_move(p_cli, p_cons->name_len + NRF_CLI_INITIAL_CURS_POS - p_cons->cur_x);
+ }
+ /* align data buffer pointer with cursor position */
+ p_cli->p_ctx->cmd_buff_pos = 0;
+}
+
+/* Function moves cursor to end of command. */
+static void cursor_end_position_move(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->cur_x_end) && (p_cons->cur_y == p_cons->cur_y_end))
+ {
+ return; /* nothing to handle because cursor is in end position */
+ }
+
+ if (p_cons->cur_y_end > p_cons->cur_y)
+ {
+ cursor_down_move(p_cli, p_cons->cur_y_end - p_cons->cur_y);
+ }
+
+ if (p_cons->cur_x > p_cons->cur_x_end)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x - p_cons->cur_x_end);
+ }
+ else
+ {
+ cursor_right_move(p_cli, p_cons->cur_x_end - p_cons->cur_x);
+ }
+ /* align data buffer pointer with cursor position */
+ p_cli->p_ctx->cmd_buff_pos = p_cli->p_ctx->cmd_buff_len;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+/* Function reads cursor position from terminal. */
+static ret_code_t cursor_position_get(nrf_cli_t const * p_cli)
+{
+ size_t cnt;
+ uint16_t x = 0; /* horizontal position */
+ uint16_t y = 0; /* vertical position */
+ char c = 0;
+
+ nrf_cli_cmd_len_t buff_idx = 0;
+
+ /* clear temp buffer */
+ memset(p_cli->p_ctx->temp_buff, 0, sizeof(p_cli->p_ctx->temp_buff));
+
+ /* escape code asking terminal about its size */
+ static char const cmd_get_terminal_size[] = "\033[6n";
+
+ nrf_fprintf(p_cli->p_fprintf_ctx, cmd_get_terminal_size);
+ /* fprintf buffer needs to be flushed to start sending prepared escape code to the terminal */
+ transport_buffer_flush(p_cli);
+
+ /* timeout for terminal response = ~1s */
+ for (uint16_t i = 0; i < 1000; i++)
+ {
+ do
+ {
+ cli_read(p_cli, &c, sizeof(c), &cnt);
+ if (cnt == 0)
+ {
+ nrf_delay_us(999);
+ continue;
+ }
+ if ((c != NRF_CLI_VT100_ASCII_ESC) &&
+ (p_cli->p_ctx->temp_buff[0] != NRF_CLI_VT100_ASCII_ESC))
+ {
+ continue;
+ }
+
+ if (c == 'R') /* end of response from the terminal */
+ {
+ p_cli->p_ctx->temp_buff[buff_idx] = '\0';
+ if (p_cli->p_ctx->temp_buff[1] != '[')
+ {
+ p_cli->p_ctx->temp_buff[0] = 0;
+ return NRF_ERROR_INVALID_DATA;
+ }
+ buff_idx = 2; /* index start position in the buffer where 'y' is stored */
+ while (p_cli->p_ctx->temp_buff[buff_idx] != ';')
+ {
+ y = y * 10 + (p_cli->p_ctx->temp_buff[buff_idx++] - '0');
+ if (buff_idx >= NRF_CLI_CMD_BUFF_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ }
+ if (++buff_idx >= NRF_CLI_CMD_BUFF_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ while (p_cli->p_ctx->temp_buff[buff_idx] != '\0')
+ {
+ x = x * 10 + (p_cli->p_ctx->temp_buff[buff_idx++] - '0');
+ if (buff_idx >= NRF_CLI_CMD_BUFF_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ }
+ /* horizontal cursor position */
+ if (x > NRF_CLI_MAX_TERMINAL_SIZE)
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_x = NRF_CLI_MAX_TERMINAL_SIZE;
+ }
+ else
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_x = (nrf_cli_cmd_len_t)x;
+ }
+ /* vertical cursor position */
+ if (y > NRF_CLI_MAX_TERMINAL_SIZE)
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_y = NRF_CLI_MAX_TERMINAL_SIZE;
+ }
+ else
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_y = (nrf_cli_cmd_len_t)y;
+ }
+ p_cli->p_ctx->temp_buff[0] = 0;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ p_cli->p_ctx->temp_buff[buff_idx] = c;
+ }
+
+ if (++buff_idx > NRF_CLI_CURSOR_POSITION_BUFFER - 1)
+ {
+ p_cli->p_ctx->temp_buff[0] = 0;
+ /* data_buf[NRF_CLI_CURSOR_POSITION_BUFFER - 1] is reserved for '\0' */
+ return NRF_ERROR_NO_MEM;
+ }
+
+ } while (cnt > 0);
+ }
+ return NRF_ERROR_TIMEOUT;
+}
+
+/* Function gets terminal width and height. */
+static ret_code_t terminal_size_get(nrf_cli_t const * p_cli,
+ nrf_cli_cmd_len_t * p_length,
+ nrf_cli_cmd_len_t * p_height)
+{
+ ASSERT(p_length);
+ ASSERT(p_height);
+
+ uint16_t x;
+ uint16_t y;
+
+ if (cursor_position_get(p_cli) == NRF_SUCCESS)
+ {
+ x = p_cli->p_ctx->vt100_ctx.cons.cur_x;
+ y = p_cli->p_ctx->vt100_ctx.cons.cur_y;
+ /* assumption: terminal widht and height < 999 */
+ cursor_right_move(p_cli, NRF_CLI_MAX_TERMINAL_SIZE); /* move to last column */
+ cursor_down_move(p_cli, NRF_CLI_MAX_TERMINAL_SIZE); /* move to last row */
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (cursor_position_get(p_cli) == NRF_SUCCESS)
+ {
+ *p_length = p_cli->p_ctx->vt100_ctx.cons.cur_x;
+ *p_height = p_cli->p_ctx->vt100_ctx.cons.cur_y;
+ cursor_left_move(p_cli, *p_length - x);
+ cursor_up_move(p_cli, *p_height - y);
+
+ return NRF_SUCCESS;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+static void vt100_color_set(nrf_cli_t const * p_cli, nrf_cli_vt100_color_t color)
+{
+ if (color != NRF_CLI_DEFAULT)
+ {
+ if (p_cli->p_ctx->vt100_ctx.col.col == color)
+ {
+ return;
+ }
+
+ uint8_t cmd[] = NRF_CLI_VT100_COLOR(color - 1);
+
+ p_cli->p_ctx->vt100_ctx.col.col = color;
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd);
+ }
+ else
+ {
+ static uint8_t const cmd[] = NRF_CLI_VT100_MODESOFF;
+
+ p_cli->p_ctx->vt100_ctx.col.col = color;
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd);
+ }
+}
+
+static void vt100_bgcolor_set(nrf_cli_t const * p_cli, nrf_cli_vt100_color_t bgcolor)
+{
+ if (bgcolor != NRF_CLI_DEFAULT)
+ {
+ if (p_cli->p_ctx->vt100_ctx.col.bgcol == bgcolor)
+ {
+ return;
+ }
+ /* -1 because default value is first in enum */
+ uint8_t cmd[] = NRF_CLI_VT100_BGCOLOR(bgcolor - 1);
+
+ p_cli->p_ctx->vt100_ctx.col.bgcol = bgcolor;
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd);
+ }
+}
+
+static inline void vt100_colors_store(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_colors_t * p_color)
+{
+ memcpy(p_color, &p_cli->p_ctx->vt100_ctx.col, sizeof(nrf_cli_vt100_colors_t));
+}
+
+static void vt100_colors_restore(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_colors_t const * p_color)
+{
+ vt100_color_set(p_cli, p_color->col);
+ vt100_bgcolor_set(p_cli, p_color->bgcol);
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+
+static void left_arrow_handle(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->name_len + NRF_CLI_INITIAL_CURS_POS) &&
+ (p_cons->cur_y == NRF_CLI_INITIAL_CURS_POS))
+ {
+ return; /* nothing to handle because cursor is in start position */
+ }
+
+ if (p_cons->cur_x == NRF_CLI_INITIAL_CURS_POS)
+ { /* go to previous line */
+ cursor_up_move(p_cli, 1);
+ cursor_right_move(p_cli, p_cons->terminal_wid);
+ --p_cli->p_ctx->cmd_buff_pos;
+ }
+ else
+ {
+ cursor_left_move(p_cli, 1);
+ --p_cli->p_ctx->cmd_buff_pos;
+ }
+}
+
+static void right_arrow_handle(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->cur_x_end) &&
+ (p_cons->cur_y == p_cons->cur_y_end))
+ {
+ return; /* nothing to handle because cursor is in start position */
+ }
+
+ if (p_cons->cur_x == p_cons->terminal_wid) /* go to next line */
+ {
+ cursor_down_move(p_cli, 1);
+ cursor_left_move(p_cli, p_cons->terminal_wid);
+ ++p_cli->p_ctx->cmd_buff_pos;
+ }
+ else
+ {
+ cursor_right_move(p_cli, 1);
+ ++p_cli->p_ctx->cmd_buff_pos;
+ }
+}
+
+static inline void char_insert_echo_off(nrf_cli_t const * p_cli, char data)
+{
+ if (p_cli->p_ctx->cmd_buff_len >= (NRF_CLI_CMD_BUFF_SIZE - 1))
+ {
+ return;
+ }
+
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos++] = data;
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = '\0';
+ ++p_cli->p_ctx->cmd_buff_len;
+}
+
+static void char_insert(nrf_cli_t const * p_cli, char data)
+{
+ nrf_cli_cmd_len_t diff;
+ bool ins_mode = (bool)p_cli->p_ctx->internal.flag.insert_mode;
+
+ diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ if (!ins_mode)
+ {
+ if (p_cli->p_ctx->cmd_buff_len >= (NRF_CLI_CMD_BUFF_SIZE - 1))
+ {
+ return;
+ }
+ if (diff > 0)
+ {
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos + 1],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ diff);
+ }
+ }
+ else
+ {
+ if ((p_cli->p_ctx->cmd_buff_len >= (NRF_CLI_CMD_BUFF_SIZE - 1)) &&
+ (diff == 0))
+ {
+ /* If cmd buffer is full, it is possible to replace chars but adding new
+ is not allowed. */
+ return;
+ }
+ }
+
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = data;
+
+ if (!ins_mode)
+ {
+ p_cli->p_ctx->cmd_buff[++p_cli->p_ctx->cmd_buff_len] = '\0';
+ }
+
+ if (diff > 0)
+ {
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ /* Below if-else statement is to minimize esc codes transmission. */
+ if (last_line)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ /* Move cursor one position left less in case of insert mode. */
+ cursor_left_move(p_cli, diff - ins_mode);
+ }
+ else
+ {
+ /* Save the current cursor position in order to get back after fprintf function. */
+ cli_cursor_save(p_cli);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_cursor_restore(p_cli);
+ /* Move cursor right by one position to edit the next character. */
+ cursor_right_move(p_cli, 1);
+ }
+ }
+ else
+ {
+ /* New char appended at the end of buffer. */
+ if (ins_mode)
+ {
+ p_cli->p_ctx->cmd_buff[++p_cli->p_ctx->cmd_buff_len] = '\0';
+ }
+ cli_putc(p_cli, data);
+ }
+
+ /* Incrementation needs to be executed before invoking function: cursor_in_empty_line. */
+ ++p_cli->p_ctx->cmd_buff_pos;
+
+ /* Forcing terminal to switch to a new line if the command is too long. */
+ if (cursor_in_empty_line(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ return;
+ }
+
+ if (full_line_cmd(p_cli))
+ {
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ /* The code below will force the terminal to scroll one line down when the currently entered command
+ * reaches lower right corner of the terminal screen. */
+ cursor_down_move(p_cli, p_cons->cur_y_end - p_cons->cur_y - 1);
+ cursor_next_line_move(p_cli);
+ cursor_up_move(p_cli, p_cons->cur_y_end - p_cons->cur_y);
+ cursor_right_move(p_cli, p_cons->cur_x - 1);
+ return;
+ }
+}
+
+static void char_backspace(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t diff;
+
+ if ((p_cli->p_ctx->cmd_buff_len == 0) || (p_cli->p_ctx->cmd_buff_pos == 0))
+ {
+ return;
+ }
+
+ diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos - 1],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ diff + 1);
+
+ --p_cli->p_ctx->cmd_buff_pos;
+ --p_cli->p_ctx->cmd_buff_len;
+
+ if (diff > 0)
+ {
+ cli_putc(p_cli, NRF_CLI_VT100_ASCII_BSPACE);
+
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ if (last_line)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_clear_eos(p_cli);
+ cursor_left_move(p_cli, diff);
+ }
+ else
+ {
+ /* If cursor is not in last cmd line, its position needs to be saved by
+ * VT100 command. */
+ cli_cursor_save(p_cli);
+ cli_clear_eos(p_cli);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_cursor_restore(p_cli);
+ }
+ }
+ else
+ {
+ static char const cmd_bspace[] = {
+ NRF_CLI_VT100_ASCII_BSPACE, ' ', NRF_CLI_VT100_ASCII_BSPACE, '\0'};
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd_bspace);
+ }
+}
+
+static void char_delete(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t diff;
+
+ diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ if (diff == 0)
+ {
+ return;
+ }
+
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos + 1],
+ diff);
+
+ --p_cli->p_ctx->cmd_buff_len;
+
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ /* If last line of command is edited, there is no need for saving cursor position. */
+ if (last_line)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEAREOL);
+ cursor_left_move(p_cli, --diff);
+ }
+ else
+ {
+ cli_cursor_save(p_cli);
+ cli_clear_eos(p_cli);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_cursor_restore(p_cli);
+ }
+}
+
+static char make_argv(size_t * p_argc, char ** pp_argv, char * p_cmd, uint8_t max_argc)
+{
+ char c;
+ char quote = 0;
+
+ *p_argc = 0;
+ do
+ {
+ c = *p_cmd;
+ if (c == '\0')
+ {
+ break;
+ }
+
+ if (isspace((int)c))
+ {
+ *p_cmd++ = '\0';
+ continue;
+ }
+
+ pp_argv[(*p_argc)++] = p_cmd;
+ quote = 0;
+
+ while (1)
+ {
+ c = *p_cmd;
+
+ if (c == '\0')
+ {
+ break;
+ }
+
+ if (!quote)
+ {
+ switch (c)
+ {
+ case '\\':
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ p_cmd += 1;
+ continue;
+
+ case '\'':
+ case '\"':
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ quote = c;
+ continue;
+ default:
+ break;
+ }
+ }
+
+ if (quote == c)
+ {
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ quote = 0;
+ continue;
+ }
+
+ if (quote && c == '\\')
+ {
+ char t = *(p_cmd + 1);
+
+ if (t == quote)
+ {
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ p_cmd += 1;
+ continue;
+ }
+
+ if (t == '0')
+ {
+ uint8_t i;
+ uint8_t v = 0;
+
+ for (i = 2; i < (2 + 3); i++)
+ {
+ t = *(p_cmd + i);
+
+ if (t >= '0' && t <= '7')
+ {
+ v = (v << 3) | (t - '0');
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (i > 2)
+ {
+ memmove(p_cmd, p_cmd + (i - 1), cli_strlen(p_cmd) - (i - 2));
+ *p_cmd++ = v;
+ continue;
+ }
+ }
+
+ if (t == 'x')
+ {
+ uint8_t i;
+ uint8_t v = 0;
+
+ for (i = 2; i < (2 + 2); i++)
+ {
+ t = *(p_cmd + i);
+
+ if (t >= '0' && t <= '9')
+ {
+ v = (v << 4) | (t - '0');
+ }
+ else if (t >= 'a' && t <= 'f')
+ {
+ v = (v << 4) | (t - 'a' + 10);
+ }
+ else if (t >= 'A' && t <= 'F')
+ {
+ v = (v << 4) | (t - 'A' + 10);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (i > 2)
+ {
+ memmove(p_cmd, p_cmd + (i - 1), cli_strlen(p_cmd) - (i - 2));
+ *p_cmd++ = v;
+ continue;
+ }
+ }
+ }
+ if (!quote && isspace((int)c))
+ {
+ break;
+ }
+
+ p_cmd += 1;
+ }
+ } while (*p_argc < max_argc);
+
+ ASSERT(*p_argc <= NRF_CLI_ARGC_MAX);
+ pp_argv[*p_argc] = 0;
+
+ return quote;
+}
+
+static void cli_state_set(nrf_cli_t const * p_cli, nrf_cli_state_t state)
+{
+ p_cli->p_ctx->state = state;
+
+ if (state == NRF_CLI_STATE_ACTIVE)
+ {
+ p_cli->p_ctx->cmd_buff[0] = '\0'; /* clear command buffer */
+ p_cli->p_ctx->cmd_buff_pos = 0;
+ p_cli->p_ctx->cmd_buff_len = 0;
+ nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "%s", p_cli->p_name);
+ }
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+static inline void history_mode_exit(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->p_cmd_list_element = NULL;
+}
+
+static void history_handle(nrf_cli_t const * p_cli, bool up)
+{
+ nrf_cli_memobj_header_t header = {
+ .p_prev = NULL,
+ .p_next = NULL,
+ .cmd_len = 0
+ };
+ nrf_cli_cmd_len_t current_cmd_len;
+ bool skip = false;
+
+ if (!up) /* button down */
+ {
+ if (p_cli->p_ctx->p_cmd_list_element == NULL)
+ {
+ return;
+ }
+ cursor_home_position_move(p_cli);
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ p_cli->p_ctx->p_cmd_list_element = header.p_next;
+ current_cmd_len = p_cli->p_ctx->cmd_buff_len;
+
+ if (p_cli->p_ctx->p_cmd_list_element == NULL)
+ {
+ if (cli_strlen(p_cli->p_ctx->temp_buff) > 0)
+ {
+ strcpy(p_cli->p_ctx->cmd_buff, p_cli->p_ctx->temp_buff);
+ }
+ else
+ {
+ p_cli->p_ctx->cmd_buff[0] = '\0';
+ }
+ header.cmd_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+ skip = true;
+ }
+ }
+ else /* button up */
+ {
+ if ((p_cli->p_ctx->p_cmd_list_element == p_cli->p_ctx->p_cmd_list_tail) ||
+ (p_cli->p_ctx->p_cmd_list_head == NULL))
+ {
+ /* Nothing to display. */
+ return;
+ }
+ cursor_home_position_move(p_cli);
+
+ if (p_cli->p_ctx->p_cmd_list_element == NULL)
+ {
+ current_cmd_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+
+ p_cli->p_ctx->p_cmd_list_element = p_cli->p_ctx->p_cmd_list_head;
+ /* Save the currently entered and not executed command. */
+ if (current_cmd_len > 0)
+ {
+ strcpy(p_cli->p_ctx->temp_buff, p_cli->p_ctx->cmd_buff);
+ }
+ else
+ {
+ p_cli->p_ctx->temp_buff[0] = '\0';
+ }
+ }
+ else
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+ current_cmd_len = header.cmd_len;
+ p_cli->p_ctx->p_cmd_list_element = header.p_prev;
+ }
+ }
+ if (!skip)
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ p_cli->p_ctx->cmd_buff,
+ header.cmd_len + 1, /* +1 for '\0' */
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+ }
+
+ p_cli->p_ctx->cmd_buff_pos = header.cmd_len;
+ p_cli->p_ctx->cmd_buff_len = header.cmd_len;
+
+ if (current_cmd_len > header.cmd_len)
+ {
+ cli_clear_eos(p_cli);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff);
+ if (cursor_in_empty_line(p_cli) || full_line_cmd(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+}
+
+static void history_list_element_add(nrf_cli_t const * p_cli, nrf_memobj_t * p_memobj)
+{
+ ASSERT(p_memobj != NULL);
+
+ nrf_cli_memobj_header_t header;
+
+ if (p_cli->p_ctx->p_cmd_list_head == NULL)
+ {
+ p_cli->p_ctx->p_cmd_list_head = p_memobj;
+ p_cli->p_ctx->p_cmd_list_tail = p_memobj;
+ header.p_prev = NULL;
+ header.p_next = NULL;
+ header.cmd_len = p_cli->p_ctx->cmd_buff_len;
+ }
+ else
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_head,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ header.p_next = p_memobj;
+
+ nrf_memobj_write(p_cli->p_ctx->p_cmd_list_head,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ header.p_next = NULL;
+ header.p_prev = p_cli->p_ctx->p_cmd_list_head;
+ header.cmd_len = p_cli->p_ctx->cmd_buff_len;
+
+ p_cli->p_ctx->p_cmd_list_head = p_memobj;
+ }
+
+ nrf_memobj_write(p_memobj,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ nrf_memobj_write(p_memobj,
+ p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff_len + 1, /* +1 for '\0' */
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+}
+
+static void history_list_element_oldest_remove(nrf_cli_t const * p_cli)
+{
+ if (p_cli->p_ctx->p_cmd_list_tail == NULL)
+ {
+ return; // nothing to do
+ }
+
+ nrf_cli_memobj_header_t header;
+ nrf_memobj_t * p_memobj = p_cli->p_ctx->p_cmd_list_tail;
+
+ nrf_memobj_read(p_memobj,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ p_cli->p_ctx->p_cmd_list_tail = header.p_next;
+ memset(&header, 0, sizeof(nrf_cli_memobj_header_t));
+ nrf_memobj_write(p_memobj, &header, NRF_CLI_HISTORY_HEADER_SIZE, 0);
+ nrf_memobj_free(p_memobj);
+
+ /* Checking if memory objects list is empty. */
+ if (p_cli->p_ctx->p_cmd_list_tail == NULL)
+ {
+ p_cli->p_ctx->p_cmd_list_head = NULL;
+ return;
+ }
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_tail,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ header.p_prev = NULL;
+ nrf_memobj_write(p_cli->p_ctx->p_cmd_list_tail, &header, NRF_CLI_HISTORY_HEADER_SIZE, 0);
+}
+
+static void history_list_free_memory(nrf_cli_t const * p_cli)
+{
+ while (p_cli->p_ctx->p_cmd_list_tail != NULL)
+ {
+ history_list_element_oldest_remove(p_cli);
+ }
+}
+
+static void history_save(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t cmd_new_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+
+ history_mode_exit(p_cli);
+
+ if (cmd_new_len == 0)
+ {
+ return;
+ }
+
+ /* Checking if newly entered command is not duplicated with previous one. */
+ if (p_cli->p_ctx->p_cmd_list_head != NULL)
+ {
+ nrf_cli_memobj_header_t header;
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_head,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+ if (cmd_new_len == header.cmd_len)
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_head,
+ p_cli->p_ctx->temp_buff,
+ header.cmd_len + 1, /* +1 for '\0' */
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+
+ if (strcmp(p_cli->p_ctx->cmd_buff, p_cli->p_ctx->temp_buff) == 0)
+ {
+ /* Duplicated command, nothing to save. */
+ p_cli->p_ctx->temp_buff[0] = '\0';
+ return;
+ }
+ p_cli->p_ctx->temp_buff[0] = '\0';
+ }
+ }
+
+ for (size_t idx = 0; idx < NRF_CLI_HISTORY_ELEMENT_COUNT; idx++)
+ {
+ nrf_memobj_t * p_memobj;
+
+ p_memobj = nrf_memobj_alloc(p_cli->p_cmd_hist_mempool,
+ ((size_t)NRF_CLI_HISTORY_HEADER_SIZE + cmd_new_len + 1));
+ if (p_memobj != NULL)
+ {
+ history_list_element_add(p_cli, p_memobj);
+ return;
+ }
+ else
+ {
+ history_list_element_oldest_remove(p_cli);
+ }
+ }
+ return;
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+
+/* Function checks how many identical characters have two strings starting from the first character. */
+static nrf_cli_cmd_len_t str_similarity_check(char const * str_a, char const * str_b)
+{
+ nrf_cli_cmd_len_t cnt = 0;
+
+ while (str_a[cnt] != '\0')
+ {
+ if (str_a[cnt] != str_b[cnt])
+ {
+ return cnt;
+ }
+
+ if (++cnt == 0)
+ {
+ return --cnt; /* too long strings */
+ }
+ }
+ return cnt;
+}
+
+static void completion_insert(nrf_cli_t const * p_cli,
+ char const * p_compl,
+ nrf_cli_cmd_len_t compl_len)
+{
+ ASSERT (p_compl);
+
+ nrf_cli_cmd_len_t diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ if ((p_cli->p_ctx->cmd_buff_len + compl_len > NRF_CLI_CMD_BUFF_SIZE - 1) ||
+ (compl_len == 0))
+ {
+ return;
+ }
+
+ /* Make space for completion. */
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos + compl_len],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ diff + 1); /* + 1 for '\0' */
+
+ /* Insert completion. */
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ p_compl,
+ compl_len);
+
+ p_cli->p_ctx->cmd_buff_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ p_cli->p_ctx->cmd_buff_pos += compl_len;
+
+ if (cursor_in_empty_line(p_cli) || full_line_cmd(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+
+ if (diff > 0)
+ {
+ cursor_position_synchronize(p_cli);
+ }
+}
+
+static void option_print(nrf_cli_t const * p_cli,
+ char const * p_option,
+ nrf_cli_cmd_len_t longest_option)
+{
+ static char const * tab = " ";
+
+ /* Function initialization has been requested. */
+ if (p_option == NULL)
+ {
+ p_cli->p_ctx->vt100_ctx.printed_cmd = 0;
+ return;
+ }
+ longest_option += cli_strlen(tab);
+
+ nrf_cli_cmd_len_t columns =
+ (p_cli->p_ctx->vt100_ctx.cons.terminal_wid - cli_strlen(tab)) / longest_option;
+ nrf_cli_cmd_len_t diff = longest_option - cli_strlen(p_option);
+
+ if (p_cli->p_ctx->vt100_ctx.printed_cmd++ % columns == 0)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_OPTION, "\r\n%s%s", tab, p_option);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_OPTION, "%s", p_option);
+ }
+ cursor_right_move(p_cli, diff);
+}
+
+static void cli_tab_handle(nrf_cli_t const * p_cli)
+{
+ size_t cmd_idx;
+ size_t cmd_last = 0;
+ size_t cmd_first = 0;
+
+ size_t argc;
+ char * argv[NRF_CLI_ARGC_MAX + 1]; /* +1 reserved for NULL in function make_argv */
+
+ nrf_cli_cmd_len_t cmd_lvl = NRF_CLI_CMD_ROOT_LVL;
+ nrf_cli_cmd_len_t cmd_longest = 0; /* longest matching command */
+
+ /* Calculating the longest possible completion length. -1 for '\0'. */
+ nrf_cli_cmd_len_t compl_len = (NRF_CLI_CMD_BUFF_SIZE - 1) - p_cli->p_ctx->cmd_buff_len;
+
+ if (compl_len == 0)
+ {
+ return;
+ }
+
+ /* Copy command from its beginning to cursor position. */
+ memcpy(p_cli->p_ctx->temp_buff,
+ p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff_pos);
+
+ p_cli->p_ctx->temp_buff[p_cli->p_ctx->cmd_buff_pos] = '\0';
+
+ /* Check if the current cursor position points to the 'space' character. */
+ bool space = isspace((int)p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos - 1]);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ /* If the Tab key is pressed, "history mode" must be terminated because tab and history handlers
+ are sharing the same array: temp_buff. */
+ history_mode_exit(p_cli);
+#endif
+
+ /* Create argument list. */
+ (void)make_argv(&argc,
+ &argv[0],
+ p_cli->p_ctx->temp_buff,
+ NRF_CLI_ARGC_MAX);
+
+ nrf_cli_cmd_len_t arg_len = cli_strlen(argv[cmd_lvl]);
+
+ /* Variable 'static_entry' is needed to handle dynamic commands. */
+ nrf_cli_static_entry_t static_entry;
+
+ nrf_cli_cmd_entry_t const * p_cmd = NULL;
+ nrf_cli_static_entry_t const * p_st_cmd = NULL;
+ nrf_cli_static_entry_t const * p_st_cmd_last = NULL;
+
+ do
+ {
+ if ((argc == 0) ||
+ (cmd_lvl >= argc - 1 + space))
+ {
+ if (space)
+ {
+ arg_len = 0;
+ }
+ else
+ {
+ arg_len = cli_strlen(argv[cmd_lvl]);
+ }
+
+ cmd_idx = 0;
+
+ while (1)
+ {
+ cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (p_st_cmd == NULL)
+ {
+ /* No more commands available. */
+ break;
+ }
+
+ if (strncmp(argv[cmd_lvl], p_st_cmd->p_syntax, arg_len) != 0)
+ {
+ if (p_st_cmd_last != NULL)
+ {
+ /* No more matches will be found as commands are sorted alphabetically. */
+ break;
+ }
+ continue;
+ }
+ if (p_st_cmd_last == NULL)
+ {
+ cmd_first = cmd_idx - 1;
+ cmd_longest = cli_strlen(p_st_cmd->p_syntax);
+ if (compl_len > (cmd_longest - arg_len))
+ {
+ compl_len = cmd_longest - arg_len;
+ }
+ }
+ else
+ {
+ nrf_cli_cmd_len_t len = cli_strlen(p_st_cmd->p_syntax);
+ if (len > cmd_longest)
+ {
+ cmd_longest = len;
+ }
+
+ if (compl_len > 0) /* Checking if partial completion is possible */
+ {
+ nrf_cli_static_entry_t last_entry;
+ cmd_get(p_cmd, cmd_lvl, cmd_last, &p_st_cmd_last, &last_entry);
+
+ len = str_similarity_check(p_st_cmd->p_syntax + arg_len,
+ p_st_cmd_last->p_syntax + arg_len);
+ if (compl_len > len)
+ {
+ /* Determining the longest possible completion. */
+ compl_len = len;
+ }
+ }
+ }
+ cmd_last = cmd_idx - 1;
+ p_st_cmd_last = p_st_cmd;
+
+ if (cmd_idx == 0) /* Too many possibilities */
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, NRF_CLI_MSG_TAB_OVERFLOWED);
+ break;
+ }
+ }
+ }
+ else
+ {
+ cmd_idx = 0;
+
+ while (1)
+ {
+ cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (cmd_idx == 0)
+ {
+ /* No match found and commands counter overflowed. */
+ nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, NRF_CLI_MSG_TAB_OVERFLOWED);
+ return;
+ }
+
+ if (p_st_cmd == NULL) /* No more commands available */
+ {
+ return;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ /* Ignore wildcard character arguments if they are "standalone". Example:
+ 1. log enable info b*<tab> -> "b*" is treated as a command so no match found
+ 2. log enable info b* <tab> -> "b* " is ignored, <tab> will prompt all available
+ commands. */
+ if (wildcard_character_exist(argv[cmd_lvl]))
+ {
+ break;
+ }
+#endif
+ /* Fuction "strcmp" is used because an exact match is required. */
+ if (strcmp(argv[cmd_lvl], p_st_cmd->p_syntax) == 0)
+ {
+ p_cmd = p_st_cmd->p_subcmd;
+ break;
+ }
+ }
+ }
+
+ if ((p_cmd == NULL) || (p_st_cmd == NULL))
+ {
+ break;
+ }
+
+ } while (++cmd_lvl < argc + space);
+
+ if (p_st_cmd_last == NULL)
+ {
+ /* No match found. */
+ return;
+ }
+
+ if (cmd_first == cmd_last) /* only one match found */
+ {
+ if (p_cmd->is_dynamic)
+ {
+ /* In case of dynamic entry, function cmd_get shall be called again for matching
+ * command index (cmd_last). It is because static_entry is most likely appended by
+ * not valid data.
+ */
+ cmd_get(p_cmd, cmd_lvl, cmd_last, &p_st_cmd_last, &static_entry);
+ }
+ if (cli_strlen(p_st_cmd_last->p_syntax) != arg_len) /* no exact match found */
+ {
+ completion_insert(p_cli, p_st_cmd_last->p_syntax + arg_len, compl_len);
+ }
+
+ /* Next character in the buffer is not 'space'. */
+ if (!isspace((int)p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]))
+ {
+ if (p_cli->p_ctx->internal.flag.insert_mode)
+ {
+ p_cli->p_ctx->internal.flag.insert_mode = 0;
+ char_insert(p_cli, ' ');
+ p_cli->p_ctx->internal.flag.insert_mode = 1;
+ }
+ else
+ {
+ char_insert(p_cli, ' ');
+ }
+ }
+ else
+ {
+ /* case:
+ | | -> cursor
+ cons_name $: valid_cmd valid_sub_cmd| |argument <tab>
+ */
+ cursor_position_increment(p_cli);
+ /* result:
+ cons_name $: valid_cmd valid_sub_cmd |a|rgument
+ */
+ }
+ return;
+ }
+
+ /* Printing all matching commands (options). */
+ option_print(p_cli, NRF_CLI_INIT_OPTION_PRINTER, cmd_longest);
+ for (cmd_idx = cmd_first; cmd_idx <= cmd_last; cmd_idx++)
+ {
+ cmd_get(p_cmd, cmd_lvl, cmd_idx, &p_st_cmd, &static_entry);
+ option_print(p_cli, p_st_cmd->p_syntax, cmd_longest);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r\n%s", p_cli->p_name);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff);
+
+ cursor_position_synchronize(p_cli);
+ completion_insert(p_cli, p_st_cmd_last->p_syntax + arg_len, compl_len);
+}
+
+#define NRF_CLI_ASCII_MAX_CHAR (127u)
+static inline ret_code_t ascii_filter(char const data)
+{
+ return (uint8_t)data > NRF_CLI_ASCII_MAX_CHAR ? NRF_ERROR_INVALID_DATA : NRF_SUCCESS;
+}
+
+static void cli_state_collect(nrf_cli_t const * p_cli)
+{
+ size_t count = 0;
+ char data;
+
+ while (1)
+ {
+ cli_read(p_cli, &data, sizeof(data), &count);
+ if (count == 0)
+ {
+ return;
+ }
+
+ if (ascii_filter(data) != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_PWR_MGMT)
+ nrf_pwr_mgmt_feed();
+#endif
+
+ switch (p_cli->p_ctx->receive_state)
+ {
+ case NRF_CLI_RECEIVE_DEFAULT:
+ if (data == p_cli->newline_char)
+ {
+ if (p_cli->p_ctx->cmd_buff_len == 0)
+ {
+ cursor_next_line_move(p_cli);
+ }
+ else
+ {
+ /* Command execution */
+ cli_execute(p_cli);
+ }
+ cli_state_set(p_cli, NRF_CLI_STATE_ACTIVE);
+ return;
+ }
+ switch (data)
+ {
+ case NRF_CLI_VT100_ASCII_ESC: /* ESCAPE */
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_ESC);
+ break;
+ case '\0':
+ break;
+ case '\t': /* TAB */
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ cli_tab_handle(p_cli);
+ }
+ break;
+ case NRF_CLI_VT100_ASCII_BSPACE: /* BACKSPACE */
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ char_backspace(p_cli);
+ }
+ break;
+ case NRF_CLI_VT100_ASCII_DEL: /* DELETE */
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ char_delete(p_cli);
+ }
+ break;
+ default:
+ if (isprint((int)data))
+ {
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ char_insert(p_cli, data);
+ }
+ else
+ {
+ char_insert_echo_off(p_cli, data);
+ }
+ }
+ break;
+ }
+ break;
+ case NRF_CLI_RECEIVE_ESC:
+ if (data == '[')
+ {
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_ESC_SEQ);
+ }
+ else
+ {
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_DEFAULT);
+ }
+ break;
+ case NRF_CLI_RECEIVE_ESC_SEQ:
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_DEFAULT);
+
+ if (!cli_flag_echo_is_set(p_cli))
+ {
+ return;
+ }
+
+ switch (data)
+ {
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ case 'A': /* UP arrow */
+ history_handle(p_cli, true);
+ break;
+ case 'B': /* DOWN arrow */
+ history_handle(p_cli, false);
+ break;
+#endif
+ case 'C': /* RIGHT arrow */
+ right_arrow_handle(p_cli);
+ break;
+ case 'D': /* LEFT arrow */
+ left_arrow_handle(p_cli);
+ break;
+ case 'F': /* END Button */
+ cursor_end_position_move(p_cli);
+ break;
+ case 'H': /* HOME Button */
+ cursor_home_position_move(p_cli);
+ break;
+ case 'L': /* INSERT Button */
+ p_cli->p_ctx->internal.flag.insert_mode ^= 1;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_DEFAULT);
+ break;
+ }
+ }
+}
+
+/* Function remove white chars from beginning and end of command buffer. */
+static void cmd_trim(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t i = 0;
+
+ if (p_cli->p_ctx->cmd_buff[0] == '\0') /* no command in the buffer */
+ {
+ return;
+ }
+
+ /* Counting white characters starting from beginning of the command. */
+ while (isspace((int)p_cli->p_ctx->cmd_buff[i++]))
+ {
+ if (i == 0)
+ {
+ p_cli->p_ctx->cmd_buff[0] = '\0';
+ return;
+ }
+ }
+
+ /* Removing counted white characters. */
+ if (--i > 0)
+ {
+ memmove(p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff + i,
+ (p_cli->p_ctx->cmd_buff_len + 1) - i); /* +1 for '\0' */
+ p_cli->p_ctx->cmd_buff_len = p_cli->p_ctx->cmd_buff_len - i;
+ p_cli->p_ctx->cmd_buff_pos = p_cli->p_ctx->cmd_buff_len;
+ }
+
+ /* Counting white characters starting from end of command. */
+ char * p_end = &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_len - 1];
+ i = 0;
+ while (isspace((int)*p_end))
+ {
+ ++i;
+ --p_end;
+ }
+
+ /* Removing counted white characters. */
+ if (p_end != &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_len - 1])
+ {
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_len - i] = '\0';
+ p_cli->p_ctx->cmd_buff_len = p_cli->p_ctx->cmd_buff_len - i;
+ p_cli->p_ctx->cmd_buff_pos = p_cli->p_ctx->cmd_buff_len;
+ }
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+static void spaces_trim(char * p_char)
+{
+ nrf_cli_cmd_len_t shift = 0;
+ nrf_cli_cmd_len_t len = cli_strlen(p_char);
+
+ if (p_char == NULL)
+ {
+ return;
+ }
+
+ for (nrf_cli_cmd_len_t i = 0; i < len - 1; i++)
+ {
+ if (isspace((int)p_char[i]))
+ {
+ for (nrf_cli_cmd_len_t j = i + 1; j < len; j++)
+ {
+ if (isspace((int)p_char[j]))
+ {
+ shift++;
+ continue;
+ }
+ if (shift > 0)
+ {
+ memmove(&p_char[i + 1], &p_char[j], len - shift + 1); // +1 for EOS
+ len -= shift;
+ shift = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Adds new command and one space just before pattern */
+static bool command_to_tmp_buffer_add(nrf_cli_t const * p_cli,
+ char const * p_new_cmd,
+ char const * p_pattern)
+{
+ nrf_cli_cmd_len_t cmd_len = cli_strlen(p_new_cmd);
+ nrf_cli_cmd_len_t shift;
+ char * p_cmd_source_addr;
+
+ /* +1 for space */
+ if (((size_t)p_cli->p_ctx->cmd_tmp_buff_len + cmd_len + 1) > NRF_CLI_CMD_BUFF_SIZE)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_WARNING,
+ "Command buffer is too short to expand all commands matching "
+ "wildcard pattern\r\n");
+ return false;
+ }
+
+ p_cmd_source_addr = strstr(p_cli->p_ctx->temp_buff, p_pattern);
+
+ if (p_cmd_source_addr == NULL)
+ {
+ return false;
+ }
+
+ shift = cli_strlen(p_cmd_source_addr);
+
+ /* make place for new command: + 1 for space + 1 for EOS */
+ memmove(p_cmd_source_addr + cmd_len + 1, p_cmd_source_addr, shift + 1);
+ memcpy(p_cmd_source_addr, p_new_cmd, cmd_len);
+ p_cmd_source_addr[cmd_len] = ' ';
+
+ p_cli->p_ctx->cmd_tmp_buff_len += cmd_len + 1; // + 1 for space
+
+ return true;
+}
+
+/* removes pattern and following space */
+static void pattern_from_tmp_buffer_remove(nrf_cli_t const * p_cli,
+ char const * p_pattern)
+{
+ size_t shift;
+ char * p_pattern_addr = strstr(p_cli->p_ctx->temp_buff, p_pattern);
+
+ nrf_cli_cmd_len_t pattern_len = cli_strlen(p_pattern);
+
+ if (p_pattern_addr == NULL)
+ {
+ return;
+ }
+
+ if (p_pattern_addr > p_cli->p_ctx->temp_buff)
+ {
+ if (*(p_pattern_addr - 1) == ' ')
+ {
+ pattern_len++; /* space needs to be removed as well */
+ p_pattern_addr--; /* set pointer to space */
+ }
+ }
+
+ shift = cli_strlen(p_pattern_addr) - pattern_len + 1; /* +1 for EOS */
+ p_cli->p_ctx->cmd_tmp_buff_len -= pattern_len;
+
+ memmove(p_pattern_addr, p_pattern_addr + pattern_len, shift);
+}
+
+/**
+ * @internal @brief Function for searching and adding commands matching to wildcard pattern.
+ *
+ * This function is internal to nrf_cli module and shall be not called directly.
+ *
+ * @param[in/out] p_cli Pointer to the CLI instance.
+ * @param[in] p_cmd Pointer to command which will be processed
+ * @param[in] cmd_lvl Command level in the command tree.
+ * @param[in] p_pattern Pointer to wildcard pattern.
+ * @param[out] p_counter Number of found and added commands.
+ *
+ * @retval WILDCARD_CMD_ADDED All matching commands added to the buffer.
+ * @retval WILDCARD_CMD_ADDED_MISSING_SPACE Not all matching commands added because
+ * NRF_CLI_CMD_BUFF_SIZE is too small.
+ * @retval WILDCARD_CMD_NO_MATCH_FOUND No matching command found.
+ */
+static wildcard_cmd_status_t commands_expand(nrf_cli_t const * p_cli,
+ nrf_cli_cmd_entry_t const * p_cmd,
+ size_t cmd_lvl,
+ char * p_pattern,
+ size_t * p_counter)
+{
+ size_t cmd_idx = 0;
+ size_t counter = 0;
+ bool success = false;
+
+ nrf_cli_static_entry_t static_entry;
+ nrf_cli_static_entry_t const * p_static_entry = NULL;
+ wildcard_cmd_status_t ret_val = WILDCARD_CMD_NO_MATCH_FOUND;
+
+ do
+ {
+ cmd_get(p_cmd,
+ cmd_lvl,
+ cmd_idx++,
+ &p_static_entry,
+ &static_entry);
+
+ if (p_static_entry == NULL)
+ {
+ break;
+ }
+
+ if (0 == fnmatch(p_pattern, p_static_entry->p_syntax, 0))
+ {
+ success = command_to_tmp_buffer_add(p_cli,
+ p_static_entry->p_syntax,
+ p_pattern);
+ if (!success)
+ {
+ break;
+ }
+ counter++;
+ }
+
+ } while(cmd_idx != 0);
+
+ if (counter > 0)
+ {
+ *p_counter = counter;
+ pattern_from_tmp_buffer_remove(p_cli, p_pattern);
+
+ if (success)
+ {
+ ret_val = WILDCARD_CMD_ADDED;
+ }
+ else
+ {
+ ret_val = WILDCARD_CMD_ADDED_MISSING_SPACE;
+ }
+ }
+
+ return ret_val;
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+
+/* Function is analyzing the command buffer to find matching commands. Next, it invokes the last recognized
+ * command which has a handler and passes the rest of command buffer as arguments. */
+static void cli_execute(nrf_cli_t const * p_cli)
+{
+ char quote;
+ size_t argc;
+ char * argv[NRF_CLI_ARGC_MAX + 1]; /* +1 reserved for NULL added by function make_argv */
+
+ size_t cmd_idx; /* currently analyzed command in cmd_level */
+ size_t cmd_lvl = NRF_CLI_CMD_ROOT_LVL; /* currently analyzed command level */
+ size_t cmd_handler_lvl = 0; /* last command level for which a handler has been found */
+ size_t cmd_handler_idx = 0; /* last command index for which a handler has been found */
+
+ nrf_cli_cmd_entry_t const * p_cmd = NULL;
+
+ cmd_trim(p_cli);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ history_save(p_cli);
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+/* Wildcard can be correctly handled under following conditions:
+ - wildcard command does not have a handler
+ - wildcard command is on the deepest commands level
+ - other commands on the same level as wildcard command shall also not have a handler
+
+ Algorithm:
+ 1. Command buffer is copied to Temp buffer.
+ 2. Algorithm goes through Command buffer to find handlers and subcommands.
+ 3. If algorithm will find a wildcard character it switches to Temp buffer.
+ 4. In the Temp buffer command with found wildcard character is changed into matching command(s).
+ 5. Algorithm switch back to Command buffer and analyzes next command.
+ 6. When all arguments are analyzed from Command buffer, Temp buffer is copied to Command buffer.
+ 7. Last found handler is executed with all arguments in the Command buffer.
+*/
+ size_t commands_expanded = 0;
+
+ memset(p_cli->p_ctx->temp_buff, 0, sizeof(p_cli->p_ctx->temp_buff));
+ memcpy(p_cli->p_ctx->temp_buff,
+ p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff_len);
+
+ /* Function spaces_trim must be used instead of make_argv. At this point it is important to keep
+ temp_buff as a one string. It will allow to find wildcard commands easly with strstr
+ function. */
+ spaces_trim(p_cli->p_ctx->temp_buff);
+ p_cli->p_ctx->cmd_tmp_buff_len = cli_strlen(p_cli->p_ctx->temp_buff) + 1; // +1 for EOS
+#endif
+
+ cursor_end_position_move(p_cli);
+ if (!cursor_in_empty_line(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+
+ /* create argument list */
+ quote = make_argv(&argc,
+ &argv[0],
+ p_cli->p_ctx->cmd_buff,
+ NRF_CLI_ARGC_MAX);
+
+ if (!argc)
+ {
+ cursor_next_line_move(p_cli);
+ return;
+ }
+
+ if (quote != 0)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "not terminated: %c\r\n", quote);
+ return;
+ }
+
+ /* Searching for a matching root command. */
+ for (cmd_idx = 0; cmd_idx <= CLI_DATA_SECTION_ITEM_COUNT; ++cmd_idx)
+ {
+ if (cmd_idx >= CLI_DATA_SECTION_ITEM_COUNT)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_COMMAND_NOT_FOUND);
+ return;
+ }
+
+ p_cmd = CLI_DATA_SECTION_ITEM_GET(cmd_idx);
+ if (strcmp(argv[cmd_lvl], p_cmd->u.p_static->p_syntax) != 0)
+ {
+ continue;
+ }
+ break;
+ }
+
+ /* Root command shall be always static. */
+ ASSERT(p_cmd->is_dynamic == false);
+
+ /* Pointer to the deepest command level with a handler. */
+ nrf_cli_cmd_entry_t const * p_cmd_low_level_entry = NULL;
+
+ /* Memory reserved for dynamic commands. */
+ nrf_cli_static_entry_t static_entry;
+ nrf_cli_static_entry_t const * p_static_entry = NULL;
+
+ nrf_cli_cmd_handler handler_cmd_lvl_0 = p_cmd->u.p_static->handler;
+ if (handler_cmd_lvl_0 != NULL)
+ {
+ p_cli->p_ctx->p_current_stcmd = p_cmd->u.p_static;
+ }
+
+ p_cmd = p_cmd->u.p_static->p_subcmd;
+ cmd_lvl++;
+ cmd_idx = 0;
+
+ while (1)
+ {
+ if (cmd_lvl >= argc)
+ {
+ break;
+ }
+
+ if (!strcmp(argv[cmd_lvl], "-h") || !strcmp(argv[cmd_lvl], "--help"))
+ {
+ /* Command called with help option so it makes no sense to search deeper commands. */
+ cli_flag_help_set(p_cli);
+ break;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ /* Wildcard character is found */
+ if (wildcard_character_exist(argv[cmd_lvl]))
+ {
+ size_t counter = 0;
+ wildcard_cmd_status_t status;
+
+ /* Function will search commands tree for commands matching wildcard pattern stored in
+ argv[cmd_lvl]. If match is found wildcard pattern will be replaced by matching
+ commands in temp_buffer. If there is no space to add all matching commands function
+ will add as many as possible. Next it will continue to search for next wildcard
+ pattern and it will try to add matching commands. */
+ status = commands_expand(p_cli, p_cmd, cmd_lvl, argv[cmd_lvl], &counter);
+ if (WILDCARD_CMD_NO_MATCH_FOUND == status)
+ {
+ break;
+ }
+ commands_expanded += counter;
+ cmd_lvl++;
+ continue;
+ }
+#endif
+
+ cmd_get(p_cmd,
+ cmd_lvl,
+ cmd_idx++,
+ &p_static_entry,
+ &static_entry);
+
+ if ((cmd_idx == 0) || (p_static_entry == NULL))
+ {
+ break;
+ }
+
+ if (strcmp(argv[cmd_lvl], p_static_entry->p_syntax) == 0)
+ {
+ /* checking if command has a handler */
+ if (p_static_entry->handler != NULL)
+ {
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ if (commands_expanded > 0)
+ {
+ cursor_end_position_move(p_cli);
+ if (!cursor_in_empty_line(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+ /* An error occured, fnmatch argument cannot be followed by argument
+ * with a handler to avoid multiple function calls. */
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "Error: requested multiple function executions\r\n");
+ cli_flag_help_clear(p_cli);
+ return;
+ }
+#endif
+ /* Storing p_st_cmd->handler is not feasible for dynamic commands. Data will be
+ * invalid with the next loop iteration. */
+ cmd_handler_lvl = cmd_lvl;
+ cmd_handler_idx = cmd_idx - 1;
+ p_cmd_low_level_entry = p_cmd;
+ }
+ cmd_lvl++;
+ cmd_idx = 0;
+ p_cmd = p_static_entry->p_subcmd;
+ }
+ }
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ if (commands_expanded > 0)
+ {
+ /* Copy temp_buff to cmd_buff */
+ memcpy(p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->temp_buff,
+ p_cli->p_ctx->cmd_tmp_buff_len);
+ p_cli->p_ctx->cmd_buff_len = p_cli->p_ctx->cmd_tmp_buff_len;
+
+ /* calling make_arg function again because cmd_buffer has additional commads */
+ (void)make_argv(&argc,
+ &argv[0],
+ p_cli->p_ctx->cmd_buff,
+ NRF_CLI_ARGC_MAX);
+ }
+ #endif
+
+ /* Executing the deepest found handler. */
+ if (p_cmd_low_level_entry != NULL)
+ {
+ cmd_get(p_cmd_low_level_entry,
+ cmd_handler_lvl,
+ cmd_handler_idx,
+ &p_static_entry,
+ &static_entry);
+
+ p_cli->p_ctx->p_current_stcmd = p_static_entry;
+
+ p_cli->p_ctx->p_current_stcmd->handler(p_cli,
+ argc - cmd_handler_lvl,
+ &argv[cmd_handler_lvl]);
+ }
+ else if (handler_cmd_lvl_0 != NULL)
+ {
+ handler_cmd_lvl_0(p_cli, argc, &argv[0]);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, NRF_CLI_MSG_SPECIFY_SUBCOMMAND);
+ }
+ cli_flag_help_clear(p_cli);
+}
+
+/* Function required by qsort. */
+static int string_cmp(void const * pp_a, void const * pp_b)
+{
+ ASSERT(pp_a);
+ ASSERT(pp_b);
+
+ char const ** pp_str_a = (char const **)pp_a;
+ char const ** pp_str_b = (char const **)pp_b;
+
+ return strcmp(*pp_str_a, *pp_str_b);
+}
+
+static void cli_transport_evt_handler(nrf_cli_transport_evt_t evt_type, void * p_context)
+{
+ nrf_cli_t * p_cli = (nrf_cli_t *)p_context;
+ ASSERT(p_cli);
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ task_events_set(p_cli->p_ctx->task_id, evt_type == NRF_CLI_TRANSPORT_EVT_RX_RDY ?
+ NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT : NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT);
+#else
+
+ if (evt_type == NRF_CLI_TRANSPORT_EVT_RX_RDY)
+ {
+
+ }
+ else
+ {
+ /* wr done evt */
+ p_cli->p_ctx->internal.flag.tx_rdy = 1;
+ }
+#endif
+}
+
+static ret_code_t nrf_cli_instance_init(nrf_cli_t const * p_cli,
+ void const * p_config,
+ bool use_colors)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+ ASSERT((p_cli->newline_char == '\n') || (p_cli->newline_char == '\r'));
+
+#if defined(NRF_CLI_LOG_BACKEND) && NRF_CLI_LOG_BACKEND
+ p_cli->p_log_backend->p_cli = p_cli;
+#endif
+ ret_code_t ret = p_cli->p_iface->p_api->init(p_cli->p_iface,
+ p_config,
+ cli_transport_evt_handler,
+ (void *)p_cli);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ ASSERT(p_cli->p_cmd_hist_mempool);
+ ret = nrf_memobj_pool_init(p_cli->p_cmd_hist_mempool);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ p_cli->p_ctx->p_cmd_list_head = NULL;
+ p_cli->p_ctx->p_cmd_list_tail = NULL;
+#endif
+
+ memset(p_cli->p_ctx, 0, sizeof(nrf_cli_ctx_t));
+ p_cli->p_ctx->internal.flag.tx_rdy = 1;
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ p_cli->p_ctx->internal.flag.use_colors = use_colors;
+#endif
+ p_cli->p_ctx->internal.flag.echo = NRF_CLI_ECHO_STATUS;
+ p_cli->p_ctx->state = NRF_CLI_STATE_INITIALIZED;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid = NRF_CLI_DEFAULT_TERMINAL_WIDTH;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_hei = NRF_CLI_DEFAULT_TERMINAL_HEIGHT;
+
+ const char * * pp_sorted_cmds = (const char * *)CLI_SORTED_CMD_PTRS_START_ADDR_GET;
+ for (size_t i = 0; i < CLI_DATA_SECTION_ITEM_COUNT; i++)
+ {
+ const nrf_cli_cmd_entry_t * cmd;
+ cmd = CLI_DATA_SECTION_ITEM_GET(i);
+
+ /* NULL syntax commands not allowed. */
+ ASSERT(cmd);
+ ASSERT(cmd->u.p_static->p_syntax);
+
+ pp_sorted_cmds[i] = cmd->u.p_static->p_syntax;
+ }
+
+ if (CLI_DATA_SECTION_ITEM_COUNT > 0)
+ {
+ qsort(pp_sorted_cmds,
+ CLI_DATA_SECTION_ITEM_COUNT,
+ sizeof (char *),
+ string_cmp);
+ }
+
+ return NRF_SUCCESS;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+static ret_code_t nrf_cli_instance_uninit(nrf_cli_t const * p_cli);
+void console_task(void * p_context)
+{
+ nrf_cli_t * p_cli = (nrf_cli_t *)p_context;
+
+ ret_code_t ret = nrf_cli_start(p_cli);
+ APP_ERROR_CHECK(ret);
+
+ while (1)
+ {
+ uint32_t evts = task_events_wait(NRF_CLI_TASK_EVTS);
+
+ if (evts & NRF_CLI_KILL_TASK_EVT)
+ {
+ (void)nrf_cli_instance_uninit(p_cli);
+ task_exit();
+ }
+ else
+ {
+ nrf_cli_process(p_cli);
+ }
+ }
+}
+#endif
+
+ret_code_t nrf_cli_init(nrf_cli_t const * p_cli,
+ void const * p_config,
+ bool use_colors,
+ bool log_backend,
+ nrf_log_severity_t init_lvl)
+{
+ ASSERT(p_cli);
+
+ ret_code_t err_code = nrf_cli_instance_init(p_cli, p_config, use_colors);
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+ if ((err_code == NRF_SUCCESS) && log_backend && NRF_CLI_LOG_BACKEND)
+ {
+ int32_t id = nrf_log_backend_add(&p_cli->p_log_backend->backend, init_lvl);
+ if (id < 0)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ nrf_log_backend_enable(&p_cli->p_log_backend->backend);
+ }
+#endif
+ return err_code;
+}
+
+ret_code_t nrf_cli_task_create(nrf_cli_t const * p_cli)
+{
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ p_cli->p_ctx->task_id = task_create(console_task, p_cli->p_name,(void *)p_cli);
+ if (p_cli->p_ctx->task_id == TASK_ID_INVALID)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+static ret_code_t nrf_cli_instance_uninit(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (cli_flag_processing_is_set(p_cli))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+ if (p_cli->p_log_backend != NULL)
+ {
+ nrf_log_backend_disable(&p_cli->p_log_backend->backend);
+ nrf_log_backend_remove(&p_cli->p_log_backend->backend);
+ }
+#endif
+
+ ret_code_t ret = p_cli->p_iface->p_api->uninit(p_cli->p_iface);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ history_list_free_memory(p_cli);
+#endif
+
+ memset(p_cli->p_ctx, 0, sizeof(nrf_cli_ctx_t));
+ p_cli->p_ctx->state = NRF_CLI_STATE_UNINITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli)
+{
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ if (cli_flag_processing_is_set(p_cli))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ task_events_set(p_cli->p_ctx->task_id, NRF_CLI_KILL_TASK_EVT);
+ return NRF_SUCCESS;
+#else
+ return nrf_cli_instance_uninit(p_cli);
+#endif
+}
+
+ret_code_t nrf_cli_start(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (p_cli->p_ctx->state != NRF_CLI_STATE_INITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ void * p_context = (void *)((uint32_t)task_id_get());
+ p_cli->p_log_backend->p_context = p_context;
+#endif
+
+ ret_code_t err_code = p_cli->p_iface->p_api->enable(p_cli->p_iface, false);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ task_events_set(task_id_get(), NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT);
+#endif
+
+ if (err_code == NRF_SUCCESS)
+ {
+#if NRF_CLI_VT100_COLORS_ENABLED
+ vt100_color_set(p_cli, NRF_CLI_NORMAL);
+ vt100_bgcolor_set(p_cli, NRF_CLI_VT100_COLOR_BLACK);
+#endif
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\r\n\n");
+ cli_state_set(p_cli, NRF_CLI_STATE_ACTIVE);
+ }
+
+ return err_code;
+}
+
+ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (p_cli->p_ctx->state == NRF_CLI_STATE_INITIALIZED ||
+ p_cli->p_ctx->state == NRF_CLI_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ cli_state_set(p_cli, NRF_CLI_STATE_INITIALIZED);
+ return NRF_SUCCESS;
+}
+
+void nrf_cli_process(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ nrf_cli_internal_t internal;
+ internal.value = 0;
+ internal.flag.processing = 1;
+ (void)nrf_atomic_u32_or((nrf_atomic_u32_t *)&p_cli->p_ctx->internal.value,
+ internal.value);
+
+ switch (p_cli->p_ctx->state)
+ {
+ case NRF_CLI_STATE_UNINITIALIZED:
+ case NRF_CLI_STATE_INITIALIZED:
+ /* Console initialized but not started. */
+ break;
+ case NRF_CLI_STATE_ACTIVE:
+ {
+ cli_state_collect(p_cli);
+ bool log_processed = cli_log_entry_process(p_cli, false);
+ if (log_processed)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "%s", p_cli->p_name);
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff);
+ cursor_position_synchronize(p_cli);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ transport_buffer_flush(p_cli);
+ internal.value = (uint32_t)0xFFFFFFFF;
+ internal.flag.processing = 0;
+ (void)nrf_atomic_u32_and((nrf_atomic_u32_t *)&p_cli->p_ctx->internal.value,
+ internal.value);
+}
+
+/* Function shall be only used by the nrf_fprintf module. */
+void nrf_cli_print_stream(void const * p_user_ctx, char const * p_data, size_t data_len)
+{
+ cli_write((nrf_cli_t const *)p_user_ctx,
+ p_data,
+ data_len,
+ NULL);
+}
+
+void nrf_cli_fprintf(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_color_t color,
+ char const * p_fmt,
+ ...)
+{
+ ASSERT(p_fmt);
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ va_list args = {0};
+ va_start(args, p_fmt);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ if ((p_cli->p_ctx->internal.flag.use_colors) &&
+ (color != p_cli->p_ctx->vt100_ctx.col.col))
+ {
+ nrf_cli_vt100_colors_t col;
+
+ vt100_colors_store(p_cli, &col);
+ vt100_color_set(p_cli, color);
+
+ nrf_fprintf_fmt(p_cli->p_fprintf_ctx, p_fmt, &args);
+
+ vt100_colors_restore(p_cli, &col);
+ }
+ else
+#endif // NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ {
+ nrf_fprintf_fmt(p_cli->p_fprintf_ctx, p_fmt, &args);
+ }
+
+ va_end(args);
+}
+
+/* Function prints a string on terminal screen with requested margin.
+ * It takes care to not divide words.
+ * p_cli Pointer to CLI instance.
+ * p_str Pointer to string to be printed.
+ * terminal_offset Requested left margin.
+ * offset_first_line Add margin to the first printed line.
+ */
+static void format_offset_string_print(nrf_cli_t const * p_cli,
+ char const * p_str,
+ size_t terminal_offset,
+ bool offset_first_line)
+{
+ if (p_str == NULL)
+ {
+ return;
+ }
+
+ if (offset_first_line)
+ {
+ cursor_right_move(p_cli, terminal_offset);
+ }
+
+ size_t length;
+ size_t offset = 0;
+
+ /* Skipping whitespace. */
+ while (isspace((int)*(p_str + offset)))
+ {
+ ++offset;
+ }
+
+ while (1)
+ {
+ size_t idx = 0;
+ length = cli_strlen(p_str) - offset;
+
+ if (length <= p_cli->p_ctx->vt100_ctx.cons.terminal_wid - terminal_offset)
+ {
+ for (idx = 0; idx < length; idx++)
+ {
+ if (*(p_str + offset + idx) == '\n')
+ {
+ transport_buffer_flush(p_cli);
+ cli_write(p_cli, p_str + offset, idx, NULL);
+ offset += idx + 1;
+ cursor_next_line_move(p_cli);
+ cursor_right_move(p_cli, terminal_offset);
+ break;
+ }
+ }
+ /* String will fit in one line. */
+ nrf_fprintf(p_cli->p_fprintf_ctx, p_str + offset);
+ break;
+ }
+ else
+ {
+ /* String is longer than terminal line so text needs to divide in the way
+ to not divide words. */
+ length = p_cli->p_ctx->vt100_ctx.cons.terminal_wid - terminal_offset;
+
+ while (1)
+ {
+ /* Determining line break. */
+ if (isspace((int)(*(p_str + offset + idx))))
+ {
+ length = idx;
+ if (*(p_str + offset + idx) == '\n')
+ {
+ break;
+ }
+ }
+ if ((idx + terminal_offset) >= p_cli->p_ctx->vt100_ctx.cons.terminal_wid)
+ {
+ /* End of line reached. */
+ break;
+ }
+ ++idx;
+ }
+
+ /* Writing one line, fprintf IO buffer must be flushed before calling cli_write. */
+ transport_buffer_flush(p_cli);
+ cli_write(p_cli, p_str + offset, length, NULL);
+ offset += length;
+
+ /* Calculating text offset to ensure that next line will not begin with a space. */
+ while (isspace((int)(*(p_str + offset))))
+ {
+ ++offset;
+ }
+ cursor_next_line_move(p_cli);
+ cursor_right_move(p_cli, terminal_offset);
+ }
+ }
+ cursor_next_line_move(p_cli);
+}
+
+void nrf_cli_help_print(nrf_cli_t const * p_cli,
+ nrf_cli_getopt_option_t const * p_opt,
+ size_t opt_len)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ static uint8_t const tab_len = 2;
+ static char const opt_sep[] =", "; /* options separator */
+ static char const help[] = "-h, --help";
+ static char const cmd_sep[] = " - "; /* command separator */
+ uint16_t field_width = 0;
+ uint16_t longest_string = cli_strlen(help) - cli_strlen(opt_sep);
+
+ /* Printing help string for command. */
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s%s",
+ p_cli->p_ctx->p_current_stcmd->p_syntax,
+ cmd_sep);
+
+ field_width = cli_strlen(p_cli->p_ctx->p_current_stcmd->p_syntax) + cli_strlen(cmd_sep);
+ format_offset_string_print(p_cli, p_cli->p_ctx->p_current_stcmd->p_help, field_width, false);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Options:\r\n");
+
+ /* Looking for the longest option string. */
+ if ((opt_len > 0) && (p_opt != NULL))
+ {
+ for (size_t i = 0; i < opt_len; ++i)
+ {
+ if (cli_strlen(p_opt[i].p_optname_short) + cli_strlen(p_opt[i].p_optname)
+ > longest_string)
+ {
+ longest_string = cli_strlen(p_opt[i].p_optname_short)
+ + cli_strlen(p_opt[i].p_optname);
+ }
+ }
+ }
+ longest_string += cli_strlen(opt_sep) + tab_len;
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %-*s:",
+ longest_string,
+ help);
+
+ /* Print help string for options (only -h and --help). */
+ field_width = longest_string + tab_len + 1; /* tab_len + 1 == " " and ':' from: " %-*s:" */
+ format_offset_string_print(p_cli, "Show command help.", field_width, false);
+
+ /* Formating and printing all available options (except -h, --help). */
+ if (p_opt != NULL)
+ {
+ for (size_t i = 0; i < opt_len; ++i)
+ {
+ if ((p_opt[i].p_optname_short != NULL) && (p_opt[i].p_optname != NULL))
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %s%s%s",
+ p_opt[i].p_optname_short,
+ opt_sep,
+ p_opt[i].p_optname);
+ field_width = longest_string + tab_len;
+ cursor_right_move(p_cli,
+ field_width - ( cli_strlen(p_opt[i].p_optname_short)
+ + cli_strlen(p_opt[i].p_optname)
+ + tab_len
+ + cli_strlen(opt_sep)));
+ cli_putc(p_cli, ':');
+ ++field_width; /* incrementing because char ':' was already printed above */
+ }
+ else if (p_opt[i].p_optname_short != NULL)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %-*s:",
+ longest_string,
+ p_opt[i].p_optname_short);
+ /* tab_len + 1 == " " and ':' from: " %-*s:" */
+ field_width = longest_string + tab_len + 1;
+ }
+ else if (p_opt[i].p_optname != NULL)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %-*s:",
+ longest_string,
+ p_opt[i].p_optname);
+ /* tab_len + 1 == " " and ':' from: " %-*s:" */
+ field_width = longest_string + tab_len + 1;
+ }
+ else
+ {
+ /* Do nothing. */
+ }
+
+ if (p_opt[i].p_optname_help != NULL)
+ {
+ format_offset_string_print(p_cli, p_opt[i].p_optname_help, field_width, false);
+ }
+ else
+ {
+ cursor_next_line_move(p_cli);
+ }
+ }
+ }
+
+ /* Checking if there are any subcommands avilable. */
+ if (p_cli->p_ctx->p_current_stcmd->p_subcmd == NULL)
+ {
+ return;
+ }
+
+ /* Printing formatted help of one level deeper subcommands. */
+ nrf_cli_static_entry_t static_entry;
+ nrf_cli_cmd_entry_t const * p_cmd = p_cli->p_ctx->p_current_stcmd->p_subcmd;
+ nrf_cli_static_entry_t const * p_st_cmd = NULL;
+
+ field_width = 0;
+ longest_string = 0;
+
+ size_t cmd_idx = 0;
+
+ /* Searching for the longest subcommand to print. */
+ while (1)
+ {
+ cmd_get(p_cmd, !NRF_CLI_CMD_ROOT_LVL, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (p_st_cmd == NULL)
+ {
+ break;
+ }
+ if (cli_strlen(p_st_cmd->p_syntax) > longest_string)
+ {
+ longest_string = cli_strlen(p_st_cmd->p_syntax);
+ }
+ }
+
+ /* Checking if there are dynamic subcommands. */
+ if (cmd_idx == 1)
+ {
+ /* No dynamic subcommands available. */
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Subcommands:\r\n");
+
+ /* Printing subcommands and help string (if exists). */
+ cmd_idx = 0;
+ while (1)
+ {
+ cmd_get(p_cmd, !NRF_CLI_CMD_ROOT_LVL, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (p_st_cmd == NULL)
+ {
+ break;
+ }
+
+ field_width = longest_string + tab_len;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL," %-*s:", field_width, p_st_cmd->p_syntax);
+ field_width += tab_len + 1; /* tab_len + 1 == " " and ':' from: " %-*s:" */
+
+ if (p_st_cmd->p_help != NULL)
+ {
+ format_offset_string_print(p_cli, p_st_cmd->p_help, field_width, false);
+ }
+ else
+ {
+ cursor_next_line_move(p_cli);
+ }
+ }
+}
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+
+#define NRF_CLI_LOG_MSG_OVERFLOW_MSK ((uint32_t)7)
+static bool cli_log_entry_process(nrf_cli_t const * p_cli, bool skip)
+{
+ nrf_log_entry_t entry;
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ bool print_msg = false;
+#endif
+
+ if (nrf_queue_pop(p_cli->p_log_backend->p_queue, &entry) != NRF_SUCCESS)
+ {
+ return false;
+ }
+
+ if (skip)
+ {
+ nrf_memobj_put(entry);
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ ++p_cli->p_ctx->statistics.log_lost_cnt;
+ if ((p_cli->p_ctx->statistics.log_lost_cnt & NRF_CLI_LOG_MSG_OVERFLOW_MSK) == 1)
+ {
+ /* Set flag to print a message after clearing the currently entered command. */
+ print_msg = true;
+ }
+ else
+#endif
+ {
+ return true;
+ }
+ }
+ {
+ /* Erasing the currently displayed command and console name. */
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if (p_cons->cur_y > NRF_CLI_INITIAL_CURS_POS)
+ {
+ cursor_up_move(p_cli, p_cons->cur_y - NRF_CLI_INITIAL_CURS_POS);
+ }
+
+ if (p_cons->cur_x > NRF_CLI_INITIAL_CURS_POS)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x - NRF_CLI_INITIAL_CURS_POS);
+ }
+ cli_clear_eos(p_cli);
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ if (print_msg)
+ {
+ /* Print the requested string and exit function. */
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Lost logs - increase log backend queue size.\r\n");
+
+ return true;
+ }
+#endif
+
+ /* Printing logs from the queue. */
+ do
+ {
+ nrf_log_header_t header;
+ uint32_t memobj_offset = 0;
+ nrf_log_str_formatter_entry_params_t params;
+
+ nrf_memobj_read(entry, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset = HEADER_SIZE * sizeof(uint32_t);
+
+ params.timestamp = header.timestamp;
+ params.module_id = header.module_id;
+ params.dropped = header.dropped;
+ params.use_colors = NRF_LOG_USES_COLORS; /* Color will be provided by the console application. */
+
+ if (header.base.generic.type == HEADER_TYPE_STD)
+ {
+ char const * p_log_str = (char const *)((uint32_t)header.base.std.addr);
+ params.severity = (nrf_log_severity_t)header.base.std.severity;
+ uint32_t nargs = header.base.std.nargs;
+ uint32_t args[6];
+
+ nrf_memobj_read(entry, args, nargs*sizeof(uint32_t), memobj_offset);
+ nrf_log_std_entry_process(p_log_str,
+ args,
+ nargs,
+ &params,
+ p_cli->p_fprintf_ctx);
+ }
+ else if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t data_len;
+ uint8_t data_buf[8];
+ uint32_t chunk_len;
+
+ data_len = header.base.hexdump.len;
+ params.severity = (nrf_log_severity_t)header.base.hexdump.severity;
+
+ do
+ {
+ chunk_len = sizeof(data_buf) > data_len ? data_len : sizeof(data_buf);
+ nrf_memobj_read(entry, data_buf, chunk_len, memobj_offset);
+ memobj_offset += chunk_len;
+ data_len -= chunk_len;
+ nrf_log_hexdump_entry_process(data_buf, chunk_len, &params, p_cli->p_fprintf_ctx);
+ } while (data_len > 0);
+ }
+
+ nrf_memobj_put(entry);
+ } while (nrf_queue_pop(p_cli->p_log_backend->p_queue, &entry) == NRF_SUCCESS);
+ return true;
+}
+
+static void nrf_log_backend_cli_put(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_msg)
+{
+ nrf_cli_log_backend_t * p_backend_cli = CONTAINER_OF(p_backend, nrf_cli_log_backend_t, backend);
+ nrf_cli_t const * p_cli = p_backend_cli->p_cli;
+
+ //If panic mode cannot be handled, stop handling new requests.
+ if (p_cli->p_ctx->state != NRF_CLI_STATE_PANIC_MODE_INACTIVE)
+ {
+ bool panic_mode = (p_cli->p_ctx->state == NRF_CLI_STATE_PANIC_MODE_ACTIVE);
+ //If there is no place for a new log entry, remove the oldest one.
+ ret_code_t err_code = nrf_queue_push(p_backend_cli->p_queue, &p_msg);
+ while (err_code != NRF_SUCCESS)
+ {
+ (void)cli_log_entry_process(p_cli, panic_mode ? false : true);
+
+ err_code = nrf_queue_push(p_backend_cli->p_queue, &p_msg);
+ }
+ nrf_memobj_get(p_msg);
+
+ if (panic_mode)
+ {
+ (void)cli_log_entry_process(p_cli, false);
+ }
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ else
+ {
+ task_events_set((task_id_t)((uint32_t)p_backend_cli->p_context & 0x000000FF),
+ NRF_CLI_LOG_PENDING_TASK_EVT);
+ }
+#endif
+ }
+}
+
+static void nrf_log_backend_cli_flush(nrf_log_backend_t const * p_backend)
+{
+ nrf_cli_log_backend_t * p_backend_cli;
+ nrf_cli_t const * p_cli;
+ nrf_log_entry_t * p_msg;
+
+ p_backend_cli = CONTAINER_OF(p_backend, nrf_cli_log_backend_t, backend);
+ p_cli = p_backend_cli->p_cli;
+
+ if (nrf_queue_pop(p_backend_cli->p_queue, &p_msg) == NRF_SUCCESS)
+ {
+ (void)cli_log_entry_process(p_cli, false);
+ }
+ UNUSED_PARAMETER(p_backend);
+}
+
+static void nrf_log_backend_cli_panic_set(nrf_log_backend_t const * p_backend)
+{
+ nrf_cli_log_backend_t * p_backend_cli = CONTAINER_OF(p_backend, nrf_cli_log_backend_t, backend);
+ nrf_cli_t const * p_cli = p_backend_cli->p_cli;
+
+ if (p_cli->p_iface->p_api->enable(p_cli->p_iface, true) == NRF_SUCCESS)
+ {
+ p_cli->p_ctx->state = NRF_CLI_STATE_PANIC_MODE_ACTIVE;
+ }
+ else
+ {
+ p_cli->p_ctx->state = NRF_CLI_STATE_PANIC_MODE_INACTIVE;
+ }
+}
+
+const nrf_log_backend_api_t nrf_log_backend_cli_api = {
+ .put = nrf_log_backend_cli_put,
+ .flush = nrf_log_backend_cli_flush,
+ .panic_set = nrf_log_backend_cli_panic_set,
+};
+#else
+static bool cli_log_entry_process(nrf_cli_t const * p_cli, bool skip)
+{
+ UNUSED_PARAMETER(p_cli);
+ UNUSED_PARAMETER(skip);
+ return false;
+}
+#endif // NRF_CLI_LOG_BACKEND
+
+/* ============ built-in commands ============ */
+#if NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+
+static bool nrf_cli_build_in_cmd_common_executed(nrf_cli_t const * p_cli,
+ bool arg_cnt_nok,
+ nrf_cli_getopt_option_t const * p_opt,
+ size_t opt_len)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, p_opt, opt_len);
+ return true;
+ }
+
+ if (arg_cnt_nok)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s: wrong parameter count\r\n",
+ p_cli->p_ctx->p_current_stcmd->p_syntax);
+ return true;
+ }
+
+ return false;
+}
+
+static void nrf_cli_cmd_clear(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+ UNUSED_PARAMETER(argv);
+
+ if ((argc == 2) && (nrf_cli_help_requested(p_cli)))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CURSORHOME);
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEARSCREEN);
+}
+
+static void nrf_cli_cmd_cli(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+ UNUSED_PARAMETER(argv);
+
+ if ((argc == 1) || ((argc == 2) && nrf_cli_help_requested(p_cli)) )
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, NRF_CLI_MSG_SPECIFY_SUBCOMMAND);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+static void nrf_cli_cmd_colors_off(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+ p_cli->p_ctx->internal.flag.use_colors = 0;
+}
+
+static void nrf_cli_cmd_colors_on(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+ p_cli->p_ctx->internal.flag.use_colors = 1;
+}
+
+static void nrf_cli_cmd_colors(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (argc == 1)
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 2), NULL, 0))
+ {
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+
+static void nrf_cli_cmd_echo(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc > 2), NULL, 0))
+ {
+ return;
+ }
+
+ if (argc == 2)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Echo status: %s\r\n",
+ cli_flag_echo_is_set(p_cli) ? "on" : "off");
+}
+
+static void nrf_cli_cmd_echo_off(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ cli_flag_echo_clear(p_cli);
+}
+
+static void nrf_cli_cmd_echo_on(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ cli_flag_echo_set(p_cli);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+static void nrf_cli_cmd_history(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ size_t i = 0;
+ nrf_memobj_t const * p_cmd_list = p_cli->p_ctx->p_cmd_list_tail;
+ nrf_cli_memobj_header_t header;
+
+ while (1)
+ {
+ if ((p_cmd_list == NULL) || (i >= NRF_CLI_HISTORY_ELEMENT_COUNT))
+ {
+ break;
+ }
+ nrf_memobj_read((nrf_memobj_t * )p_cmd_list,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+ nrf_memobj_read((nrf_memobj_t * )p_cmd_list,
+ p_cli->p_ctx->temp_buff,
+ header.cmd_len + 1,
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+ p_cmd_list = header.p_next;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "[%3d] %s\r\n", i++, p_cli->p_ctx->temp_buff);
+ }
+ p_cli->p_ctx->temp_buff[0] = '\0';
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+void nrf_cli_cmd_cli_stats(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (argc == 1)
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc == 2)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+ return;
+ }
+
+ UNUSED_RETURN_VALUE(nrf_cli_build_in_cmd_common_executed(p_cli, (argc > 2), NULL, 0));
+}
+
+void nrf_cli_cmd_cli_stats_show(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ uint8_t max_util = nrf_queue_max_utilization_get(p_cli->p_log_backend->p_queue);
+ uint8_t utilization = (uint8_t)(max_util * 100ul / p_cli->p_log_backend->p_queue->size);
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Lost logs: %u\r\n"
+ "Max log queue utilization: %u%% [%u/%u]\r\n",
+ p_cli->p_ctx->statistics.log_lost_cnt,
+ utilization,
+ max_util,
+ p_cli->p_log_backend->p_queue->size);
+}
+
+void nrf_cli_cmd_cli_stats_reset(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ p_cli->p_ctx->statistics.log_lost_cnt = 0;
+ nrf_queue_max_utilization_reset(p_cli->p_log_backend->p_queue);
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+
+static void nrf_cli_cmd_resize_default(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_SETCOL_80);
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid = NRF_CLI_DEFAULT_TERMINAL_WIDTH;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_hei = NRF_CLI_DEFAULT_TERMINAL_HEIGHT;
+}
+
+static void nrf_cli_cmd_resize(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (argc == 1)
+ {
+ if (terminal_size_get(p_cli,
+ &p_cli->p_ctx->vt100_ctx.cons.terminal_wid,
+ &p_cli->p_ctx->vt100_ctx.cons.terminal_hei) != NRF_SUCCESS)
+ {
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid = NRF_CLI_DEFAULT_TERMINAL_WIDTH;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_hei = NRF_CLI_DEFAULT_TERMINAL_HEIGHT;
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_WARNING,
+ "No response from the terminal, assumed 80x24 screen size\r\n");
+ }
+ return;
+ }
+
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc > 2), NULL, 0))
+ {
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_colors)
+{
+ NRF_CLI_CMD(off, NULL, NRF_CLI_HELP_COLORS_OFF, nrf_cli_cmd_colors_off),
+ NRF_CLI_CMD(on, NULL, NRF_CLI_HELP_COLORS_ON, nrf_cli_cmd_colors_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+#endif
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_echo)
+{
+ NRF_CLI_CMD(off, NULL, NRF_CLI_HELP_ECHO_OFF, nrf_cli_cmd_echo_off),
+ NRF_CLI_CMD(on, NULL, NRF_CLI_HELP_ECHO_ON, nrf_cli_cmd_echo_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_cli_stats)
+{
+ NRF_CLI_CMD(reset, NULL, NRF_CLI_HELP_STATISTICS_RESET, nrf_cli_cmd_cli_stats_reset),
+ NRF_CLI_CMD(show, NULL, NRF_CLI_HELP_STATISTICS_SHOW, nrf_cli_cmd_cli_stats_show),
+ NRF_CLI_SUBCMD_SET_END
+};
+#endif // NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_cli)
+{
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ NRF_CLI_CMD(colors, &m_sub_colors, NRF_CLI_HELP_COLORS, nrf_cli_cmd_colors),
+#endif
+ NRF_CLI_CMD(echo, &m_sub_echo, NRF_CLI_HELP_ECHO, nrf_cli_cmd_echo),
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ NRF_CLI_CMD(stats, &m_sub_cli_stats, NRF_CLI_HELP_STATISTICS, nrf_cli_cmd_cli_stats),
+#endif
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_resize)
+{
+ NRF_CLI_CMD(default, NULL, NRF_CLI_HELP_RESIZE_DEFAULT, nrf_cli_cmd_resize_default),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(clear, NULL, NRF_CLI_HELP_CLEAR, nrf_cli_cmd_clear);
+NRF_CLI_CMD_REGISTER(cli, &m_sub_cli, NRF_CLI_HELP_CLI, nrf_cli_cmd_cli);
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+NRF_CLI_CMD_REGISTER(history, NULL, NRF_CLI_HELP_HISTORY, nrf_cli_cmd_history);
+#endif
+NRF_CLI_CMD_REGISTER(resize, &m_sub_resize, NRF_CLI_HELP_RESIZE, nrf_cli_cmd_resize);
+
+#endif // NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+
+#endif // NRF_MODULE_ENABLED(NRF_CLI)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h
new file mode 100644
index 0000000..480b453
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h
@@ -0,0 +1,636 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_H__
+#define NRF_CLI_H__
+
+#include "sdk_common.h"
+#include "nrf_cli_types.h"
+#include "nrf_section.h"
+#include "nrf_log_backend_interface.h"
+#include "nrf_queue.h"
+#include "nrf_log_ctrl.h"
+#include "app_util_platform.h"
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+#include "task_manager.h"
+#endif
+
+#include "nrf_fprintf.h"
+#include "nrf_fprintf_format.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CLI_RX_BUFF_SIZE 16
+
+/* CLI reserves top task manager flags, bits 0...18 are available for application. */
+#define NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT (1UL << 19)
+#define NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT (1UL << 20)
+#define NRF_CLI_LOG_PENDING_TASK_EVT (1UL << 21)
+#define NRF_CLI_CMD_EXECUTE_EVT (1UL << 22)
+#define NRF_CLI_KILL_TASK_EVT (1UL << 23)
+
+#define NRF_CLI_TASK_EVTS (NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT | \
+ NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT | \
+ NRF_CLI_LOG_PENDING_TASK_EVT | \
+ NRF_CLI_CMD_EXECUTE_EVT | \
+ NRF_CLI_KILL_TASK_EVT)
+/**
+ * @defgroup nrf_cli Command Line Interface
+ * @ingroup app_common
+ *
+ * @brief Module for unified command line handling.
+ *
+ * @{
+ */
+
+/**
+ * @brief Aliases to: @ref nrf_cli, @ref nrf_cli_cmd_entry, and @ref nrf_cli_static_entry.
+ * Must be created here to satisfy module declaration order dependencies.
+ */
+typedef struct nrf_cli nrf_cli_t;
+typedef struct nrf_cli_cmd_entry nrf_cli_cmd_entry_t;
+typedef struct nrf_cli_static_entry nrf_cli_static_entry_t;
+
+/**
+ * @brief CLI dynamic command descriptor.
+ *
+ * @details Function shall fill the received @ref nrf_cli_static_entry structure with requested (idx)
+ * dynamic subcommand data. If there is more than one dynamic subcommand available,
+ * the function shall ensure that the returned commands: p_static->p_syntax are sorted in
+ * alphabetical order. If idx exceeds the available dynamic subcommands, the function must write
+ * to p_static->p_syntax NULL value. This will indicate to the CLI module that
+ * there are no more dynamic commands to read.
+ */
+typedef void (*nrf_cli_dynamic_get)(size_t idx, nrf_cli_static_entry_t * p_static);
+
+/**
+ * @brief CLI command descriptor.
+ */
+struct nrf_cli_cmd_entry
+{
+ bool is_dynamic;
+ union
+ {
+ nrf_cli_dynamic_get p_dynamic_get; //!< Pointer to function returning dynamic commands.
+ nrf_cli_static_entry_t const * p_static; //!< Pointer to array of static commands.
+ } u;
+};
+
+/**
+ * @brief CLI command handler prototype.
+ */
+typedef void (*nrf_cli_cmd_handler)(nrf_cli_t const * p_cli, size_t argc, char **argv);
+
+/**
+ * @brief CLI static command descriptor.
+ */
+struct nrf_cli_static_entry
+{
+ char const * p_syntax; //!< Command syntax strings.
+ char const * p_help; //!< Command help string.
+
+ nrf_cli_cmd_entry_t const * p_subcmd; //!< Pointer to subcommand.
+
+ nrf_cli_cmd_handler handler; //!< Command handler.
+};
+
+/**
+ * @brief Macro for defining and adding a root command (level 0).
+ *
+ * @note Each root command shall have unique syntax.
+ *
+ * @param[in] p_syntax Command syntax (for example: history).
+ * @param[in] p_subcmd Pointer to a subcommands array.
+ * @param[in] p_help Pointer to a command help string.
+ * @param[in] p_handler Pointer to a function handler.
+ */
+#define NRF_CLI_CMD_REGISTER(p_syntax, p_subcmd, p_help, p_handler) \
+ nrf_cli_static_entry_t const CONCAT_3(nrf_cli_, p_syntax, _raw) = \
+ NRF_CLI_CMD(p_syntax, p_subcmd, p_help, p_handler); \
+ NRF_SECTION_ITEM_REGISTER(cli_command, \
+ nrf_cli_cmd_entry_t const CONCAT_3(nrf_cli_, p_syntax, _const)) = { \
+ .is_dynamic = false, \
+ .u.p_static = &CONCAT_3(nrf_cli_, p_syntax, _raw) \
+ }; \
+ NRF_SECTION_ITEM_REGISTER(cli_sorted_cmd_ptrs, char const * CONCAT_2(p_syntax, _str_ptr))
+
+/**
+ * @brief Macro for creating a subcommand set. It must be used outside of any function body.
+ *
+ * @param[in] name Name of the subcommand set.
+ */
+#define NRF_CLI_CREATE_STATIC_SUBCMD_SET(name) \
+ /*lint -save -e85 -e31*/ \
+ static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[]; \
+ static nrf_cli_cmd_entry_t const name = { \
+ .is_dynamic = false, \
+ .u.p_static = CONCAT_2(name, _raw) \
+ }; \
+ static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[] = /*lint -restore*/
+
+/**
+ * @brief Define ending subcommands set.
+ *
+ */
+#define NRF_CLI_SUBCMD_SET_END {NULL}
+
+/**
+ * @brief Macro for creating a dynamic entry.
+ *
+ * @param[in] name Name of the dynamic entry.
+ * @param[in] p_get Pointer to the function returning dynamic commands array @ref nrf_cli_dynamic_get.
+ */
+#define NRF_CLI_CREATE_DYNAMIC_CMD(name, p_get) \
+ /*lint -save -e19*/ \
+ static nrf_cli_cmd_entry_t const name = { \
+ .is_dynamic = true, \
+ .u.p_dynamic_get = p_get \
+}; /*lint -restore*/
+
+/**
+ * @brief Initializes a CLI command (@ref nrf_cli_static_entry).
+ *
+ * @param[in] _p_syntax Command syntax (for example: history).
+ * @param[in] _p_subcmd Pointer to a subcommands array.
+ * @param[in] _p_help Pointer to a command help string.
+ * @param[in] _p_handler Pointer to a function handler.
+ */
+#define NRF_CLI_CMD(_p_syntax, _p_subcmd, _p_help, _p_handler) { \
+ .p_syntax = (const char *) STRINGIFY(_p_syntax), \
+ .p_subcmd = _p_subcmd, \
+ .p_help = (const char *) _p_help, \
+ .handler = _p_handler \
+}
+
+/**
+ * @internal @brief Internal CLI state in response to data received from the terminal.
+ */
+typedef enum
+{
+ NRF_CLI_RECEIVE_DEFAULT,
+ NRF_CLI_RECEIVE_ESC,
+ NRF_CLI_RECEIVE_ESC_SEQ
+} nrf_cli_receive_t;
+
+
+/**
+ * @internal @brief Internal CLI state.
+ */
+typedef enum
+{
+ NRF_CLI_STATE_UNINITIALIZED, //!< State uninitialized.
+ NRF_CLI_STATE_INITIALIZED, //!< State initialized but not active.
+ NRF_CLI_STATE_ACTIVE, //!< State active.
+ NRF_CLI_STATE_PANIC_MODE_ACTIVE, //!< State panic mode activated.
+ NRF_CLI_STATE_PANIC_MODE_INACTIVE //!< State panic mode requested but not supported.
+} nrf_cli_state_t;
+
+/**
+ * @brief Event type from CLI transport.
+ */
+typedef enum
+{
+ NRF_CLI_TRANSPORT_EVT_RX_RDY,
+ NRF_CLI_TRANSPORT_EVT_TX_RDY
+} nrf_cli_transport_evt_t;
+
+typedef void (*nrf_cli_transport_handler_t)(nrf_cli_transport_evt_t evt_type, void * p_context);
+
+typedef struct nrf_cli_transport_s nrf_cli_transport_t;
+
+/**
+ * @brief Unified CLI transport interface.
+ */
+typedef struct
+{
+ /**
+ * @brief Function for initializing the CLI transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ * @param[in] p_config Pointer to instance configuration.
+ * @param[in] evt_handler Event handler.
+ * @param[in] p_context Pointer to the context passed to event handler.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*init)(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context);
+
+ /**
+ * @brief Function for uninitializing the CLI transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*uninit)(nrf_cli_transport_t const * p_transport);
+
+ /**
+ * @brief Function for reconfiguring the transport to work in blocking mode.
+ *
+ * @param p_transport Pointer to the transfer instance.
+ * @param blocking If true, the transport is enabled in blocking mode.
+ *
+ * @return NRF_SUCCESS on successful enabling, error otherwise (also if not supported).
+ */
+ ret_code_t (*enable)(nrf_cli_transport_t const * p_transport,
+ bool blocking);
+
+ /**
+ * @brief Function for writing data to the transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ * @param[in] p_data Pointer to the source buffer.
+ * @param[in] length Source buffer length.
+ * @param[in] p_cnt Pointer to the sent bytes counter.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*write)(nrf_cli_transport_t const * p_transport,
+ const void * p_data,
+ size_t length,
+ size_t * p_cnt);
+
+ /**
+ * @brief Function for reading data from the transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ * @param[in] p_data Pointer to the destination buffer.
+ * @param[in] length Destination buffer length.
+ * @param[in] p_cnt Pointer to the received bytes counter.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*read)(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt);
+
+} nrf_cli_transport_api_t;
+
+struct nrf_cli_transport_s
+{
+ nrf_cli_transport_api_t const * p_api;
+};
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+/**
+ * @brief CLI history object header.
+ */
+typedef PACKED_STRUCT
+{
+ nrf_memobj_t * p_prev; //!< Pointer to the next object.
+ nrf_memobj_t * p_next; //!< Pointer to the previous object.
+ nrf_cli_cmd_len_t cmd_len; //!< Command length.
+} nrf_cli_memobj_header_t;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+typedef struct
+{
+ uint32_t log_lost_cnt; //!< Lost log counter.
+} nrf_cli_statistics_t;
+#endif
+
+/**
+ * @internal @brief Flags for internal CLI usage.
+ */
+typedef struct
+{
+ uint32_t insert_mode : 1; //!< Enables or disables console insert mode for text introduction.
+ uint32_t show_help : 1; //!< Shows help if the command was called with -h or --help parameter.
+ uint32_t use_colors : 1; //!< Enables or disables colored syntax.
+ uint32_t echo : 1; //!< Enables or disables CLI echo.
+ uint32_t processing : 1; //!< CLI is executing process function.
+ uint32_t tx_rdy : 1;
+} nrf_cli_flag_t;
+STATIC_ASSERT(sizeof(nrf_cli_flag_t) == sizeof(uint32_t));
+
+/**
+ * @internal @brief Union for internal CLI usage.
+ */
+typedef union
+{
+ uint32_t value;
+ nrf_cli_flag_t flag;
+} nrf_cli_internal_t;
+
+/**
+ * @brief CLI instance context.
+ */
+typedef struct
+{
+ nrf_cli_state_t state; //!< Internal module state.
+ nrf_cli_receive_t receive_state; //!< Escape sequence indicator.
+
+ nrf_cli_static_entry_t const * p_current_stcmd; //!< Currently executed command.
+
+ nrf_cli_vt100_ctx_t vt100_ctx; //!< VT100 color and cursor position, terminal width.
+
+ nrf_cli_cmd_len_t cmd_buff_len; //!< Command length.
+ nrf_cli_cmd_len_t cmd_buff_pos; //!< Command buffer cursor position.
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ nrf_cli_cmd_len_t cmd_tmp_buff_len; //!< Command length in tmp buffer
+#endif
+
+ char cmd_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Command input buffer.
+ char temp_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Temporary buffer used by various functions.
+ char printf_buff[NRF_CLI_PRINTF_BUFF_SIZE]; //!< Printf buffer size.
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ nrf_cli_statistics_t statistics; //!< CLI statistics.
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ task_id_t task_id;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ nrf_memobj_t * p_cmd_list_head; //!< Pointer to the head of history list.
+ nrf_memobj_t * p_cmd_list_tail; //!< Pointer to the tail of history list.
+ nrf_memobj_t * p_cmd_list_element; //!< Pointer to an element of history list.
+#endif
+ volatile nrf_cli_internal_t internal; //!< Internal CLI data
+} nrf_cli_ctx_t;
+
+extern const nrf_log_backend_api_t nrf_log_backend_cli_api;
+
+typedef struct
+{
+ nrf_log_backend_t backend;
+ nrf_queue_t const * p_queue;
+ void * p_context;
+ nrf_cli_t const * p_cli;
+} nrf_cli_log_backend_t;
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_size_) \
+ NRF_QUEUE_DEF(nrf_log_entry_t, \
+ CONCAT_2(_name_, _queue),_queue_size_, NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static nrf_cli_log_backend_t _name_ = { \
+ .backend = {.p_api = &nrf_log_backend_cli_api}, \
+ .p_queue = &CONCAT_2(_name_, _queue), \
+ }
+
+#define NRF_CLI_BACKEND_PTR(_name_) &CONCAT_2(_name_, _log_backend)
+#else
+#define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_sz_)
+#define NRF_CLI_BACKEND_PTR(_name_) NULL
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+/* Header consists memory for cmd length and pointer to: prev and next element. */
+#define NRF_CLI_HISTORY_HEADER_SIZE (sizeof(nrf_cli_memobj_header_t))
+
+#define NRF_CLI_HISTORY_MEM_OBJ(name) \
+ NRF_MEMOBJ_POOL_DEF(CONCAT_2(name, _cmd_hist_memobj), \
+ NRF_CLI_HISTORY_HEADER_SIZE + \
+ NRF_CLI_HISTORY_ELEMENT_SIZE, \
+ NRF_CLI_HISTORY_ELEMENT_COUNT)
+
+#define NRF_CLI_MEMOBJ_PTR(_name_) &CONCAT_2(_name_, _cmd_hist_memobj)
+#else
+#define NRF_CLI_MEMOBJ_PTR(_name_) NULL
+#define NRF_CLI_HISTORY_MEM_OBJ(name)
+#endif
+
+/**
+ * @brief CLI instance internals.
+ *
+ * @ref nrf_cli_t
+ */
+struct nrf_cli
+{
+ char const * const p_name; //!< Terminal name.
+
+ nrf_cli_transport_t const * p_iface; //!< Transport interface.
+ nrf_cli_ctx_t * p_ctx; //!< Internal context.
+ nrf_cli_log_backend_t * p_log_backend; //!< Logger backend.
+ nrf_fprintf_ctx_t * p_fprintf_ctx; //!< fprintf context.
+ nrf_memobj_pool_t const * p_cmd_hist_mempool; //!< Memory reserved for commands history.
+ char const newline_char; //!< New line character, only allowed values: \\n and \\r.
+};
+
+/**
+ * @brief Macro for defining a command line interface instance.
+ *
+ * @param[in] name Instance name.
+ * @param[in] cli_prefix CLI prefix string.
+ * @param[in] p_transport_iface Pointer to the transport interface.
+ * @param[in] newline_ch New line character - only allowed values are '\\n' or '\\r'.
+ * @param[in] log_queue_size Logger processing queue size.
+ */
+#define NRF_CLI_DEF(name, cli_prefix, p_transport_iface, newline_ch, log_queue_size) \
+ static nrf_cli_t const name; \
+ static nrf_cli_ctx_t CONCAT_2(name, _ctx); \
+ NRF_FPRINTF_DEF(CONCAT_2(name, _fprintf_ctx), \
+ &name, \
+ CONCAT_2(name, _ctx).printf_buff, \
+ NRF_CLI_PRINTF_BUFF_SIZE, \
+ false, \
+ nrf_cli_print_stream); \
+ NRF_LOG_BACKEND_CLI_DEF(CONCAT_2(name, _log_backend), log_queue_size); \
+ NRF_CLI_HISTORY_MEM_OBJ(name); \
+ /*lint -save -e31*/ \
+ static nrf_cli_t const name = { \
+ .p_name = cli_prefix, \
+ .p_iface = p_transport_iface, \
+ .p_ctx = &CONCAT_2(name, _ctx), \
+ .p_log_backend = NRF_CLI_BACKEND_PTR(name), \
+ .p_fprintf_ctx = &CONCAT_2(name, _fprintf_ctx), \
+ .p_cmd_hist_mempool = NRF_CLI_MEMOBJ_PTR(name), \
+ .newline_char = newline_ch \
+ } /*lint -restore*/
+
+/**
+ * @brief Function for initializing a transport layer and internal CLI state.
+ *
+ * @param[in] p_cli Pointer to CLI instance.
+ * @param[in] p_transport_config Configuration forwarded to the transport during initialization.
+ * @param[in] use_colors Enables colored prints.
+ * @param[in] log_backend If true, the console will be used as logger backend.
+ * @param[in] init_lvl Default severity level for the logger.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_init(nrf_cli_t const * p_cli,
+ void const * p_transport_config,
+ bool use_colors,
+ bool log_backend,
+ nrf_log_severity_t init_lvl);
+
+ret_code_t nrf_cli_task_create(nrf_cli_t const * p_cli);
+
+/**
+ * @brief Function for uninitializing a transport layer and internal CLI state.
+ * If function returns NRF_ERROR_BUSY, you must call @ref nrf_cli_process before calling
+ * nrf_cli_uninit again.
+ *
+ * @param p_cli Pointer to CLI instance.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli);
+
+/**
+ * @brief Function for starting CLI processing.
+ *
+ * @param p_cli Pointer to the CLI instance.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_start(nrf_cli_t const * p_cli);
+
+/**
+ * @brief Function for stopping CLI processing.
+ *
+ * @param p_cli Pointer to CLI instance.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli);
+
+/**
+ * @brief CLI colors for @ref nrf_cli_fprintf function.
+ */
+#define NRF_CLI_DEFAULT NRF_CLI_VT100_COLOR_DEFAULT /**< Turn off character attributes. */
+#define NRF_CLI_NORMAL NRF_CLI_VT100_COLOR_WHITE /**< Normal color printf. */
+#define NRF_CLI_INFO NRF_CLI_VT100_COLOR_GREEN /**< Info color printf. */
+#define NRF_CLI_OPTION NRF_CLI_VT100_COLOR_CYAN /**< Option color printf. */
+#define NRF_CLI_WARNING NRF_CLI_VT100_COLOR_YELLOW /**< Warning color printf. */
+#define NRF_CLI_ERROR NRF_CLI_VT100_COLOR_RED /**< Error color printf. */
+
+/**
+ * @brief Printf-like function which sends formatted data stream to the CLI.
+ * This function shall not be used outside of the CLI module or CLI command context.
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ * @param[in] color Printf color.
+ * @param[in] p_fmt Format string.
+ * @param[in] ... List of parameters to print.
+ */
+void nrf_cli_fprintf(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_color_t color,
+ char const * p_fmt,
+ ...);
+
+/**
+ * @brief Process function, which should be executed when data is ready in the transport interface.
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ */
+void nrf_cli_process(nrf_cli_t const * p_cli);
+
+
+/**
+ * @brief Option descriptor.
+ */
+typedef struct nrf_cli_getopt_option
+{
+ char const * p_optname; //!< Option long name.
+ char const * p_optname_short; //!< Option short name.
+ char const * p_optname_help; //!< Option help string.
+} nrf_cli_getopt_option_t;
+
+
+/**
+ * @brief Option structure initializer @ref nrf_cli_getopt_option.
+ *
+ * @param[in] _p_optname Option name long.
+ * @param[in] _p_shortname Option name short.
+ * @param[in] _p_help Option help string.
+ */
+#define NRF_CLI_OPT(_p_optname, _p_shortname, _p_help) { \
+ .p_optname = _p_optname, \
+ .p_optname_short = _p_shortname, \
+ .p_optname_help = _p_help, \
+}
+
+/**
+ * @brief Informs that a command has been called with -h or --help option.
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ *
+ * @return True if help has been requested.
+ */
+__STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli)
+{
+ return p_cli->p_ctx->internal.flag.show_help;
+}
+#endif
+
+/**
+ * @brief Prints the current command help.
+ * @details Function will print a help string with: the currently entered command, its options,
+ * and subcommands (if they exist).
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ * @param[in] p_opt Pointer to the optional option array.
+ * @param[in] opt_len Option array size.
+ */
+void nrf_cli_help_print(nrf_cli_t const * p_cli,
+ nrf_cli_getopt_option_t const * p_opt,
+ size_t opt_len);
+
+/**
+ * @internal @brief This function shall not be used directly, it is required by the
+ * nrf_fprintf module.
+ *
+ * @param[in] p_user_ctx Pointer to the context for the CLI instance.
+ * @param[in] p_data Pointer to the data buffer.
+ * @param[in] data_len Data buffer size.
+ */
+void nrf_cli_print_stream(void const * p_user_ctx, char const * p_data, size_t data_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h
new file mode 100644
index 0000000..ca4ca75
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_TYPES_H__
+#define NRF_CLI_TYPES_H__
+
+#include <inttypes.h>
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (NRF_CLI_CMD_BUFF_SIZE > 65535)
+ typedef uint32_t nrf_cli_cmd_len_t;
+#elif (NRF_CLI_CMD_BUFF_SIZE > 255)
+ typedef uint16_t nrf_cli_cmd_len_t;
+#else
+ typedef uint8_t nrf_cli_cmd_len_t;
+#endif
+
+typedef enum
+{
+ NRF_CLI_VT100_COLOR_DEFAULT,
+ NRF_CLI_VT100_COLOR_BLACK,
+ NRF_CLI_VT100_COLOR_RED,
+ NRF_CLI_VT100_COLOR_GREEN,
+ NRF_CLI_VT100_COLOR_YELLOW,
+ NRF_CLI_VT100_COLOR_BLUE,
+ NRF_CLI_VT100_COLOR_MAGENTA,
+ NRF_CLI_VT100_COLOR_CYAN,
+ NRF_CLI_VT100_COLOR_WHITE,
+
+ VT100_COLOR_END
+} nrf_cli_vt100_color_t;
+
+typedef struct
+{
+ nrf_cli_vt100_color_t col; // text color
+ nrf_cli_vt100_color_t bgcol; // background color
+} nrf_cli_vt100_colors_t;
+
+typedef struct
+{
+ nrf_cli_cmd_len_t cur_x; // horizontal cursor position in edited command line
+ nrf_cli_cmd_len_t cur_x_end; // horizontal cursor position at the end of command
+ nrf_cli_cmd_len_t cur_y; // vertical cursor position in edited command
+ nrf_cli_cmd_len_t cur_y_end; // vertical cursor position at the end of command
+ nrf_cli_cmd_len_t terminal_hei; // terminal screen height
+ nrf_cli_cmd_len_t terminal_wid; // terminal screen width
+ uint8_t name_len; // console name length
+} nrf_cli_multiline_cons_t;
+
+typedef struct
+{
+ nrf_cli_multiline_cons_t cons;
+ nrf_cli_vt100_colors_t col;
+ nrf_cli_cmd_len_t printed_cmd; // printed commands counter
+} nrf_cli_vt100_ctx_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_TYPES_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h
new file mode 100644
index 0000000..d581423
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h
@@ -0,0 +1,625 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_VT100_H__
+#define NRF_CLI_VT100_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CLI_VT100_ASCII_ESC (0x1b)
+#define NRF_CLI_VT100_ASCII_DEL (0x7F)
+#define NRF_CLI_VT100_ASCII_BSPACE (0x08)
+
+#define NRF_CLI_VT100_SETNL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'h', '\0' \
+ } /* Set new line mode */
+#define NRF_CLI_VT100_SETAPPL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'h', '\0' \
+ } /* Set cursor key to application */
+#define NRF_CLI_VT100_SETCOL_132 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'h', '\0' \
+ } /* Set number of columns to 132 */
+#define NRF_CLI_VT100_SETSMOOTH \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'h', '\0' \
+ } /* Set smooth scrolling */
+#define NRF_CLI_VT100_SETREVSCRN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'h', '\0' \
+ } /* Set reverse video on screen */
+#define NRF_CLI_VT100_SETORGREL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'h', '\0' \
+ } /* Set origin to relative */
+#define NRF_CLI_VT100_SETWRAP_ON \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'h', '\0' \
+ } /* Set auto-wrap mode */
+#define NRF_CLI_VT100_SETWRAP_OFF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
+ } /* Set auto-wrap mode */
+
+#define NRF_CLI_VT100_SETREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'h', '\0' \
+ } /* Set auto-repeat mode */
+#define NRF_CLI_VT100_SETINTER \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'h', '\0' \
+ } /* Set interlacing mode */
+
+#define NRF_CLI_VT100_SETLF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'l', '\0' \
+ } /* Set line feed mode */
+#define NRF_CLI_VT100_SETCURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'l', '\0' \
+ } /* Set cursor key to cursor */
+#define NRF_CLI_VT100_SETVT52 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '2', 'l', '\0' \
+ } /* Set VT52 (versus ANSI) */
+#define NRF_CLI_VT100_SETCOL_80 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'l', '\0' \
+ } /* Set number of columns to 80 */
+#define NRF_CLI_VT100_SETJUMP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'l', '\0' \
+ } /* Set jump scrolling */
+#define NRF_CLI_VT100_SETNORMSCRN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'l', '\0' \
+ } /* Set normal video on screen */
+#define NRF_CLI_VT100_SETORGABS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'l', '\0' \
+ } /* Set origin to absolute */
+#define NRF_CLI_VT100_RESETWRAP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
+ } /* Reset auto-wrap mode */
+#define NRF_CLI_VT100_RESETREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'l', '\0' \
+ } /* Reset auto-repeat mode */
+#define NRF_CLI_VT100_RESETINTER \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'l', '\0' \
+ } /* Reset interlacing mode */
+
+#define NRF_CLI_VT100_ALTKEYPAD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '=', '\0' \
+ } /* Set alternate keypad mode */
+#define NRF_CLI_VT100_NUMKEYPAD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '>', '\0' \
+ } /* Set numeric keypad mode */
+
+#define NRF_CLI_VT100_SETUKG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', 'A', '\0' \
+ } /* Set United Kingdom G0 character set */
+#define NRF_CLI_VT100_SETUKG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', 'A', '\0' \
+ } /* Set United Kingdom G1 character set */
+#define NRF_CLI_VT100_SETUSG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', 'B', '\0' \
+ } /* Set United States G0 character set */
+#define NRF_CLI_VT100_SETUSG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', 'B', '\0' \
+ } /* Set United States G1 character set */
+#define NRF_CLI_VT100_SETSPECG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', '0', '\0' \
+ } /* Set G0 special chars. & line set */
+#define NRF_CLI_VT100_SETSPECG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', '0', '\0' \
+ } /* Set G1 special chars. & line set */
+#define NRF_CLI_VT100_SETALTG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', '1', '\0' \
+ } /* Set G0 alternate character ROM */
+#define NRF_CLI_VT100_SETALTG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', '1', '\0' \
+ } /* Set G1 alternate character ROM */
+#define NRF_CLI_VT100_SETALTSPECG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', '2', '\0' \
+ } /* Set G0 alt char ROM and spec. graphics */
+#define NRF_CLI_VT100_SETALTSPECG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', '2', '\0' \
+ } /* Set G1 alt char ROM and spec. graphics */
+
+#define NRF_CLI_VT100_SETSS2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'N', '\0' \
+ } /* Set single shift 2 */
+#define NRF_CLI_VT100_SETSS3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', '\0' \
+ } /* Set single shift 3 */
+
+#define NRF_CLI_VT100_MODESOFF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'm', '\0' \
+ } /* Turn off character attributes */
+#define NRF_CLI_VT100_MODESOFF_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'm', '\0' \
+ } /* Turn off character attributes */
+#define NRF_CLI_VT100_BOLD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'm', '\0' \
+ } /* Turn bold mode on */
+#define NRF_CLI_VT100_LOWINT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'm', '\0' \
+ } /* Turn low intensity mode on */
+#define NRF_CLI_VT100_UNDERLINE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '4', 'm', '\0' \
+ } /* Turn underline mode on */
+#define NRF_CLI_VT100_BLINK \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '5', 'm', '\0' \
+ } /* Turn blinking mode on */
+#define NRF_CLI_VT100_REVERSE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '7', 'm', '\0' \
+ } /* Turn reverse video on */
+#define NRF_CLI_VT100_INVISIBLE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '8', 'm', '\0' \
+ } /* Turn invisible text mode on */
+
+#define NRF_CLI_VT100_SETWIN(t, b) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (t), ';', (b), 'r', '\0' \
+ } /* Set top and bottom line#s of a window */
+
+#define NRF_CLI_VT100_CURSORUP(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'A', '\0' \
+ } /* Move cursor up n lines */
+#define NRF_CLI_VT100_CURSORDN(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'B', '\0' \
+ } /* Move cursor down n lines */
+#define NRF_CLI_VT100_CURSORRT(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'C', '\0' \
+ } /* Move cursor right n lines */
+#define NRF_CLI_VT100_CURSORLF(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'D', '\0' \
+ } /* Move cursor left n lines */
+#define NRF_CLI_VT100_CURSORHOME \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'H', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_CURSORHOME_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', ';', 'H', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_CURSORPOS(v, h) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'H', '\0' \
+ } /* Move cursor to screen location v,h */
+
+#define NRF_CLI_VT100_HVHOME \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'f', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_HVHOME_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', ';', 'f', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_HVPOS(v, h) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'f', '\0' \
+ } /* Move cursor to screen location v,h */
+#define NRF_CLI_VT100_INDEX \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'D', '\0' \
+ } /* Move/scroll window up one line */
+#define NRF_CLI_VT100_REVINDEX \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'M', '\0' \
+ } /* Move/scroll window down one line */
+#define NRF_CLI_VT100_NEXTLINE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'E', '\0' \
+ } /* Move to next line */
+#define NRF_CLI_VT100_SAVECURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '7', '\0' \
+ } /* Save cursor position and attributes */
+#define NRF_CLI_VT100_RESTORECURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '8', '\0' \
+ } /* Restore cursor position and attribute */
+
+#define NRF_CLI_VT100_TABSET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'H', '\0' \
+ } /* Set a tab at the current column */
+#define NRF_CLI_VT100_TABCLR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'g', '\0' \
+ } /* Clear a tab at the current column */
+#define NRF_CLI_VT100_TABCLR_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'g', '\0' \
+ } /* Clear a tab at the current column */
+#define NRF_CLI_VT100_TABCLRALL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '3', 'g', '\0' \
+ } /* Clear all tabs */
+
+#define NRF_CLI_VT100_DHTOP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '3', '\0' \
+ } /* Double-height letters, top half */
+#define NRF_CLI_VT100_DHBOT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '4', '\0' \
+ } /* Double-height letters, bottom hal */
+#define NRF_CLI_VT100_SWSH \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '5', '\0' \
+ } /* Single width, single height letters */
+#define NRF_CLI_VT100_DWSH \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '6', '\0' \
+ } /* Double width, single height letters */
+
+#define NRF_CLI_VT100_CLEAREOL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'K', '\0' \
+ } /* Clear line from cursor right */
+#define NRF_CLI_VT100_CLEAREOL_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'K', '\0' \
+ } /* Clear line from cursor right */
+#define NRF_CLI_VT100_CLEARBOL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'K', '\0' \
+ } /* Clear line from cursor left */
+#define NRF_CLI_VT100_CLEARLINE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'K', '\0' \
+ } /* Clear entire line */
+
+#define NRF_CLI_VT100_CLEAREOS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'J', '\0' \
+ } /* Clear screen from cursor down */
+#define NRF_CLI_VT100_CLEAREOS_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'J', '\0' \
+ } /* Clear screen from cursor down */
+#define NRF_CLI_VT100_CLEARBOS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'J', '\0' \
+ } /* Clear screen from cursor up */
+#define NRF_CLI_VT100_CLEARSCREEN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'J', '\0' \
+ } /* Clear entire screen */
+
+#define NRF_CLI_VT100_DEVSTAT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '5', 'n', '\0' \
+ } /* Device status report */
+#define NRF_CLI_VT100_TERMOK \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '0', 'n', '\0' \
+ } /* Response: terminal is OK */
+#define NRF_CLI_VT100_TERMNOK \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '3', 'n', '\0' \
+ } /* Response: terminal is not OK */
+
+#define NRF_CLI_VT100_GETCURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '6', 'n', '\0' \
+ } /* Get cursor position */
+#define NRF_CLI_VT100_CURSORPOSAT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, (v), ';', (h), 'R', '\0' \
+ } /* Response: cursor is at v,h */
+
+#define NRF_CLI_VT100_IDENT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'c', '\0' \
+ } /* Identify what terminal type */
+#define NRF_CLI_VT100_IDENT_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'c', '\0' \
+ } /* Identify what terminal type */
+#define NRF_CLI_VT100_GETTYPE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', ';', (n), '0', 'c', '\0'\
+ } /* Response: terminal type code n */
+
+#define NRF_CLI_VT100_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'c', '\0' \
+ } /* Reset terminal to initial state */
+
+#define NRF_CLI_VT100_ALIGN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '8', '\0' \
+ } /* Screen alignment display */
+#define NRF_CLI_VT100_TESTPU \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', 'y', '\0' \
+ } /* Confidence power up test */
+#define NRF_CLI_VT100_TESTLB \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '2', 'y', '\0' \
+ } /* Confidence loopback test */
+#define NRF_CLI_VT100_TESTPUREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '9', 'y', '\0' \
+ } /* Repeat power up test */
+#define NRF_CLI_VT100_TESTLBREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', '0', 'y', '\0' \
+ } /* Repeat loopback test */
+
+#define NRF_CLI_VT100_LEDSOFF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'q', '\0' \
+ } /* Turn off all four leds */
+#define NRF_CLI_VT100_LED1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'q', '\0' \
+ } /* Turn on LED #1 */
+#define NRF_CLI_VT100_LED2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'q', '\0' \
+ } /* Turn on LED #2 */
+#define NRF_CLI_VT100_LED3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '3', 'q', '\0' \
+ } /* Turn on LED #3 */
+#define NRF_CLI_VT100_LED4 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '4', 'q', '\0' \
+ } /* Turn on LED #4 */
+
+/* Function Keys */
+
+#define NRF_CLI_VT100_PF1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'P', '\0' \
+ }
+#define NRF_CLI_VT100_PF2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'Q', '\0' \
+ }
+#define NRF_CLI_VT100_PF3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'R', '\0' \
+ }
+#define NRF_CLI_VT100_PF4 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'S', '\0' \
+ }
+
+/* Arrow keys */
+
+#define NRF_CLI_VT100_UP_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'A', '\0' \
+ }
+#define NRF_CLI_VT100_UP_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'A', '\0' \
+ }
+#define NRF_CLI_VT100_DOWN_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'B', '\0' \
+ }
+#define NRF_CLI_VT100_DOWN_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'B', '\0' \
+ }
+#define NRF_CLI_VT100_RIGHT_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'C', '\0' \
+ }
+#define NRF_CLI_VT100_RIGHT_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'C', '\0' \
+ }
+#define NRF_CLI_VT100_LEFT_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'D', '\0' \
+ }
+#define NRF_CLI_VT100_LEFT_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'D', '\0' \
+ }
+
+/* Numeric Keypad Keys */
+
+#define NRF_CLI_VT100_NUMERIC_0 \
+ { \
+ '0', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'p', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_1 \
+ { \
+ '1', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'q', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_2 \
+ { \
+ '2', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'r', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_3 \
+ { \
+ '3', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 's', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_4 \
+ { \
+ '4', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_4 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 't', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_5 \
+ { \
+ '5', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_5 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'u', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_6 \
+ { \
+ '6', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_6 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'v', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_7 \
+ { \
+ '7', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_7 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'w', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_8 \
+ { \
+ '8', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_8 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'x', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_9 \
+ { \
+ '9', '\0'
+#define NRF_CLI_VT100_ALT_9 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'y' \
+ }
+#define NRF_CLI_VT100_NUMERIC_MINUS \
+ { \
+ '-', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_MINUS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'm', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_COMMA \
+ { \
+ ',', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_COMMA \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'l', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_PERIOD \
+ { \
+ '.', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_PERIOD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'n', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_ENTER \
+ { \
+ ASCII_CR \
+ }
+#define NRF_CLI_VT100_ALT_ENTER \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'M', '\0' \
+ }
+
+#define NRF_CLI_VT100_COLOR(__col) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', ';', '3', '0' + (__col), 'm', '\0' \
+ }
+#define NRF_CLI_VT100_BGCOLOR(__col) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '4', '0' + (__col), 'm', '\0' \
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_VT100_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c
new file mode 100644
index 0000000..badcd04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_RTT)
+#include <SEGGER_RTT_Conf.h>
+#include <SEGGER_RTT.h>
+#include "nrf_cli_rtt.h"
+#include "nrf_assert.h"
+#include "nrf_delay.h"
+
+#define RTT_RX_TIMEOUT 100
+
+static bool m_host_present;
+
+static void timer_handler(void * p_context)
+{
+ nrf_cli_rtt_internal_t * p_internal = (nrf_cli_rtt_internal_t *)p_context;
+ if (SEGGER_RTT_HasData(0))
+ {
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, p_internal->p_cb->p_context);
+ }
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
+
+ ret_code_t err_code = app_timer_start(*p_internal->p_timer,
+ APP_TIMER_TICKS(RTT_RX_TIMEOUT),
+ p_context);
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_VARIABLE(err_code);
+}
+
+static ret_code_t cli_rtt_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ UNUSED_PARAMETER(p_config);
+
+ nrf_cli_rtt_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+ p_internal->p_cb->timer_created = false;
+
+ SEGGER_RTT_Init();
+
+ m_host_present = true;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_rtt_uninit(nrf_cli_transport_t const * p_transport)
+{
+ nrf_cli_rtt_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
+
+ return app_timer_stop(*p_internal->p_timer);
+}
+
+static ret_code_t cli_rtt_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ nrf_cli_rtt_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_stop(*p_internal->p_timer); //Timer may be running or inactive
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
+ {
+ return err_code;
+ }
+ else
+ {
+ err_code = NRF_SUCCESS;
+ }
+ }
+ if (!blocking)
+ {
+ if (!p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_create(p_internal->p_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timer_handler);
+ p_internal->p_cb->timer_created = true;
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_timer_start(*p_internal->p_timer,
+ APP_TIMER_TICKS(RTT_RX_TIMEOUT),
+ p_internal);
+ SEGGER_RTT_Init();
+ }
+ }
+ return err_code;
+}
+static ret_code_t cli_rtt_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+
+ size_t rcnt = SEGGER_RTT_Read(NRF_CLI_RTT_TERMINAL_ID, p_data, length);
+ *p_cnt = rcnt;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_rtt_write(nrf_cli_transport_t const * p_transport,
+ const void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+
+ if (!(CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk))
+ {
+ /* If an RTT session is not active, but the RTT console is processed, the program may hang.
+ * Workaround: If the debugger is not connected, always return NRF_SUCCESS.
+ */
+ *p_cnt = length;
+ return NRF_SUCCESS;
+ }
+
+ size_t idx = 0;
+ uint32_t processed;
+ uint32_t watchdog_counter = NRF_CLI_RTT_TX_RETRY_CNT;
+ const uint8_t * p_buffer = (const uint8_t *)p_data;
+ do {
+ processed = SEGGER_RTT_Write(NRF_CLI_RTT_TERMINAL_ID, &p_buffer[idx], length);
+ if (processed == 0)
+ {
+ /* There are two possible reasons for not writing any data to RTT:
+ * - The host is not connected and not reading the data.
+ * - The buffer got full and will be read by the host.
+ * These two situations are distinguished using the following algorithm.
+ * At the begining, the module assumes that the host is active,
+ * so when no data is read, it busy waits and retries.
+ * If, after retrying, the host reads the data, the module assumes that the host is active.
+ * If it fails, the module assumes that the host is inactive and stores that information. On next
+ * call, only one attempt takes place. The host is marked as active if the attempt is successful.
+ */
+ if (!m_host_present)
+ {
+ break;
+ }
+ else
+ {
+ nrf_delay_ms(NRF_CLI_RTT_TX_RETRY_DELAY_MS);
+ watchdog_counter--;
+ if (watchdog_counter == 0)
+ {
+ m_host_present = false;
+ break;
+ }
+ }
+ }
+ m_host_present = true;
+ idx += processed;
+ length -= processed;
+ } while (length);
+
+ if (idx > 0)
+ {
+ *p_cnt = idx;
+ }
+ else
+ {
+ *p_cnt = length;
+ }
+ return NRF_SUCCESS;
+}
+
+const nrf_cli_transport_api_t nrf_cli_rtt_transport_api = {
+ .init = cli_rtt_init,
+ .uninit = cli_rtt_uninit,
+ .enable = cli_rtt_enable,
+ .read = cli_rtt_read,
+ .write = cli_rtt_write,
+};
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h
new file mode 100644
index 0000000..4cb44e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_RTT_H__
+#define NRF_CLI_RTT_H__
+
+#include "nrf_cli.h"
+#include "app_timer.h"
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_cli_rtt RTT command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+extern const nrf_cli_transport_api_t nrf_cli_rtt_transport_api;
+
+/**
+ * @brief CLI RTT transport control block structure.
+ */
+typedef struct {
+ nrf_cli_transport_handler_t handler; //!< Event handler
+ void * p_context; //!< User context.
+ bool timer_created;//!< Flag indicating whether a timer is created.
+} nrf_cli_rtt_internal_cb_t;
+
+/**
+ * @brief CLI RTT transport instance structure.
+ */
+typedef struct {
+ nrf_cli_transport_t transport; //!< Transport structure.
+ nrf_cli_rtt_internal_cb_t * p_cb; //!< Pointer to the instance control block.
+ app_timer_id_t const * p_timer; //!< Pointer to the app_timer instance.
+} nrf_cli_rtt_internal_t;
+
+/**@brief CLI RTT transport definition */
+#define NRF_CLI_RTT_DEF(_name_) \
+ APP_TIMER_DEF(CONCAT_2(_name_, _timer)); \
+ static nrf_cli_rtt_internal_cb_t CONCAT_2(_name_, _cb); \
+ static const nrf_cli_rtt_internal_t _name_ = { \
+ .transport = {.p_api = &nrf_cli_rtt_transport_api}, \
+ .p_cb = &CONCAT_2(_name_, _cb), \
+ .p_timer = &CONCAT_2(_name_, _timer) \
+ }
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_RTT_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c
new file mode 100644
index 0000000..d38941a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c
@@ -0,0 +1,308 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_UART)
+#include "nrf_cli_uart.h"
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME cli_uart
+
+#define NRF_LOG_LEVEL (NRF_CLI_UART_CONFIG_LOG_ENABLED ? NRF_CLI_UART_CONFIG_LOG_LEVEL : 0)
+#define NRF_LOG_INFO_COLOR NRF_CLI_UART_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_CLI_UART_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define CLI_UART_RX_TIMEOUT 100
+
+static ret_code_t rx_try(nrf_cli_uart_internal_t * p_internal)
+{
+ ret_code_t err_code;
+ size_t len = 255;
+ uint8_t * p_data;
+
+ err_code = nrf_ringbuf_alloc(p_internal->p_rx_ringbuf, &p_data, &len, true);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if ((err_code == NRF_SUCCESS) && len)
+ {
+ err_code = nrf_drv_uart_rx(p_internal->p_uart, p_data, len);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_timer_start(*p_internal->p_timer,
+ APP_TIMER_TICKS(CLI_UART_RX_TIMEOUT),
+ p_internal);
+ }
+ }
+
+ return err_code;
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ nrf_cli_uart_internal_t * p_internal = (nrf_cli_uart_internal_t *)p_context;
+ ret_code_t err_code = NRF_SUCCESS;
+ UNUSED_VARIABLE(err_code);
+ uint8_t * p_data;
+ size_t len = 255;
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_ERROR:
+ NRF_LOG_WARNING("id:%d, evt: ERROR:%d",
+ p_internal->p_uart->inst_idx,
+ p_event->data.error.error_mask);
+ err_code = nrf_ringbuf_put(p_internal->p_rx_ringbuf, p_event->data.error.rxtx.bytes);
+ ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
+ err_code = rx_try(p_internal);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ break;
+
+ case NRF_DRV_UART_EVT_RX_DONE:
+ err_code = nrf_ringbuf_put(p_internal->p_rx_ringbuf, p_event->data.rxtx.bytes);
+ ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
+
+ if (p_event->data.rxtx.bytes)
+ {
+ NRF_LOG_INFO("id:%d, evt: RXRDY len:%d",
+ p_internal->p_uart->inst_idx,
+ p_event->data.rxtx.bytes);
+ NRF_LOG_HEXDUMP_DEBUG(p_event->data.rxtx.p_data, p_event->data.rxtx.bytes);
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY,
+ p_internal->p_cb->p_context);
+ }
+ err_code = rx_try(p_internal);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ break;
+
+ case NRF_DRV_UART_EVT_TX_DONE:
+ err_code = nrf_ringbuf_free(p_internal->p_tx_ringbuf, p_event->data.rxtx.bytes);
+ ASSERT(err_code == NRF_SUCCESS);
+ len = 255;
+ err_code = nrf_ringbuf_get(p_internal->p_tx_ringbuf, &p_data, &len, true);
+ ASSERT(err_code == NRF_SUCCESS);
+ if (len)
+ {
+ NRF_LOG_INFO("id:%d, evt uart_tx, len:%d", p_internal->p_uart->inst_idx, len);
+ err_code = nrf_drv_uart_tx(p_internal->p_uart, p_data, len);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
+ NRF_LOG_INFO("id:%d, evt: TXRDY, len:%d",
+ p_internal->p_uart->inst_idx,
+ p_event->data.rxtx.bytes);
+ break;
+
+ default:
+ NRF_LOG_ERROR("Unknown event");
+ ASSERT(false);
+ }
+}
+
+static void timer_handler(void * p_context)
+{
+ nrf_cli_uart_internal_t * p_internal = (nrf_cli_uart_internal_t *)p_context;
+ NRF_LOG_DEBUG("id:%d, evt: Timeout", p_internal->p_uart->inst_idx);
+ nrf_drv_uart_rx_abort(p_internal->p_uart);
+}
+
+static ret_code_t cli_uart_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ nrf_cli_uart_internal_t * p_internal =
+ CONTAINER_OF(p_transport,
+ nrf_cli_uart_internal_t,
+ transport);
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+ p_internal->p_cb->timer_created = false;
+ p_internal->p_cb->blocking = false;
+
+ nrf_drv_uart_config_t * p_uart_config = (nrf_drv_uart_config_t *)p_config;
+ memcpy(&p_internal->p_cb->uart_config, p_uart_config, sizeof(nrf_drv_uart_config_t));
+ p_uart_config->p_context = (void *)p_internal;
+ ret_code_t err_code = nrf_drv_uart_init(p_internal->p_uart,
+ p_uart_config,
+ uart_event_handler);
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_ringbuf_init(p_internal->p_rx_ringbuf);
+ nrf_ringbuf_init(p_internal->p_tx_ringbuf);
+ }
+ return err_code;
+}
+
+static ret_code_t cli_uart_uninit(nrf_cli_transport_t const * p_transport)
+{
+ nrf_cli_uart_internal_t * p_internal =
+ CONTAINER_OF(p_transport,
+ nrf_cli_uart_internal_t,
+ transport);
+
+ nrf_drv_uart_uninit(p_internal->p_uart);
+
+ return app_timer_stop(*p_internal->p_timer);
+}
+
+static ret_code_t cli_uart_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ nrf_cli_uart_internal_t * p_internal =
+ CONTAINER_OF(p_transport,
+ nrf_cli_uart_internal_t,
+ transport);
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_stop(*p_internal->p_timer); //Timer may be running or inactive
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
+ {
+ return err_code;
+ }
+ else
+ {
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ if (blocking)
+ {
+ nrf_drv_uart_uninit(p_internal->p_uart);
+ err_code = nrf_drv_uart_init(p_internal->p_uart, &p_internal->p_cb->uart_config, NULL);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_internal->p_cb->blocking = true;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ }
+ else
+ {
+ if (!p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_create(p_internal->p_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timer_handler);
+ p_internal->p_cb->timer_created = true;
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = rx_try(p_internal);
+ }
+ }
+ return err_code;
+}
+
+static ret_code_t cli_uart_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_uart_internal_t, transport);
+
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
+
+ if (*p_cnt)
+ {
+ NRF_LOG_INFO("id:%d, read:%d", p_instance->p_uart->inst_idx, *p_cnt);
+ }
+
+ return err_code;
+}
+
+static ret_code_t cli_uart_write(nrf_cli_transport_t const * p_transport,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_uart_internal_t, transport);
+ ret_code_t err_code;
+ *p_cnt = length;
+ err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("id:%d, write, req:%d, done:%d",
+ p_instance->p_uart->inst_idx,
+ length,
+ *p_cnt);
+
+ if (!nrf_drv_uart_tx_in_progress(p_instance->p_uart))
+ {
+ uint8_t * p_buf;
+ size_t len = 255;
+ if (nrf_ringbuf_get(p_instance->p_tx_ringbuf, &p_buf, &len, true) == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("id:%d, uart_tx, len:%d", p_instance->p_uart->inst_idx, len);
+
+ err_code = nrf_drv_uart_tx(p_instance->p_uart, p_buf, len);
+ if (p_instance->p_cb->blocking && (err_code == NRF_SUCCESS))
+ {
+ (void)nrf_ringbuf_free(p_instance->p_tx_ringbuf, len);
+ }
+ }
+ }
+ }
+ return err_code;
+}
+
+const nrf_cli_transport_api_t nrf_cli_uart_transport_api = {
+ .init = cli_uart_init,
+ .uninit = cli_uart_uninit,
+ .enable = cli_uart_enable,
+ .read = cli_uart_read,
+ .write = cli_uart_write,
+};
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h
new file mode 100644
index 0000000..1a827a4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CLI_UART_H__
+#define NRF_CLI_UART_H__
+
+#include "nrf_cli.h"
+#include "nrf_drv_uart.h"
+#include "nrf_ringbuf.h"
+#include "app_timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_cli_uart UART command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+extern const nrf_cli_transport_api_t nrf_cli_uart_transport_api;
+
+typedef struct nrf_cli_uart_internal_s nrf_cli_uart_internal_t;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+ nrf_drv_uart_config_t uart_config;
+ bool timer_created;
+ bool blocking;
+} nrf_cli_uart_internal_cb_t;
+
+struct nrf_cli_uart_internal_s {
+ nrf_cli_transport_t transport;
+ nrf_cli_uart_internal_cb_t * p_cb;
+ app_timer_id_t const * p_timer;
+ nrf_ringbuf_t const * p_rx_ringbuf;
+ nrf_ringbuf_t const * p_tx_ringbuf;
+ nrf_drv_uart_t const * p_uart;
+};
+
+typedef nrf_drv_uart_config_t nrf_cli_uart_config_t;
+
+/**@brief CLI UART transport definition.
+ *
+ * @param _name Name of the instance.
+ * @param _uart_id UART instance ID.
+ * @param _tx_buf_sz Size of TX ring buffer.
+ * @param _rx_buf_sz Size of RX ring buffer.
+ */
+#define NRF_CLI_UART_DEF(_name, _uart_id, _tx_buf_sz, _rx_buf_sz) \
+ APP_TIMER_DEF(CONCAT_2(_name, _timer)); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
+ static const nrf_drv_uart_t CONCAT_2(_name,_uart) = \
+ NRF_DRV_UART_INSTANCE(_uart_id); \
+ static nrf_cli_uart_internal_cb_t CONCAT_2(_name, _cb); \
+ static const nrf_cli_uart_internal_t _name = { \
+ .transport = {.p_api = &nrf_cli_uart_transport_api}, \
+ .p_cb = &CONCAT_2(_name, _cb), \
+ .p_timer = &CONCAT_2(_name, _timer), \
+ .p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
+ .p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
+ .p_uart = &CONCAT_2(_name,_uart), \
+ }
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_UART_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c
new file mode 100644
index 0000000..6e44955
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(CRC16)
+#include "crc16.h"
+
+#include <stdlib.h>
+
+uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc)
+{
+ uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc;
+
+ for (uint32_t i = 0; i < size; i++)
+ {
+ crc = (uint8_t)(crc >> 8) | (crc << 8);
+ crc ^= p_data[i];
+ crc ^= (uint8_t)(crc & 0xFF) >> 4;
+ crc ^= (crc << 8) << 4;
+ crc ^= ((crc & 0xFF) << 4) << 1;
+ }
+
+ return crc;
+}
+#endif //NRF_MODULE_ENABLED(CRC16)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h
new file mode 100644
index 0000000..79aac66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup crc16 CRC16 compute
+ * @{
+ * @ingroup hci_transport
+ *
+ * @brief This module implements CRC-16-CCITT (polynomial 0x1021) with 0xFFFF initial value.
+ * The data can be passed in multiple 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(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CRC16_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c
new file mode 100644
index 0000000..68d0c14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(CRC32)
+#include "crc32.h"
+
+#include <stdlib.h>
+
+uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc)
+{
+ uint32_t crc;
+
+ crc = (p_crc == NULL) ? 0xFFFFFFFF : ~(*p_crc);
+ for (uint32_t i = 0; i < size; i++)
+ {
+ crc = crc ^ p_data[i];
+ for (uint32_t j = 8; j > 0; j--)
+ {
+ crc = (crc >> 1) ^ (0xEDB88320U & ((crc & 1) ? 0xFFFFFFFF : 0));
+ }
+ }
+ return ~crc;
+}
+#endif //NRF_MODULE_ENABLED(CRC32)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h
new file mode 100644
index 0000000..d01cc8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup crc32 CRC32 compute
+ * @{
+ * @ingroup hci_transport
+ *
+ * @brief This module implements the CRC-32 calculation in the blocks.
+ */
+
+#ifndef CRC32_H__
+#define CRC32_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for calculating CRC-32 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-32 value or NULL if first call.
+ *
+ * @return The updated CRC-32 value, based on the input supplied.
+ */
+uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CRC32_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c
new file mode 100644
index 0000000..66de4bb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c
@@ -0,0 +1,887 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "ssi_aes_error.h"
+#include "cc310_backend_aes.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_AES)
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to mbed TLS. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+} nrf_crypto_backend_cc310_aes_any_context_t;
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef union
+{
+ nrf_crypto_backend_cc310_aes_any_context_t any; /**< Common for all contexts. */
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+ nrf_crypto_backend_aes_ecb_context_t ecb;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+ nrf_crypto_backend_aes_cbc_context_t cbc;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+ nrf_crypto_backend_aes_ctr_context_t ctr;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+ nrf_crypto_backend_aes_cbc_mac_context_t cbc_mac;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+ nrf_crypto_backend_aes_cmac_context_t cmac;
+#endif
+} nrf_crypto_backend_cc310_aes_context_t;
+
+
+static ret_code_t result_get(SaSiError_t error)
+{
+ ret_code_t ret_val;
+ switch (error)
+ {
+ case SASI_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case SASI_AES_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case SASI_AES_ILLEGAL_KEY_SIZE_ERROR:
+ case SASI_AES_DATA_IN_SIZE_ILLEGAL:
+ case SASI_AES_DATA_IN_BUFFER_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case SASI_AES_INVALID_IV_OR_TWEAK_PTR_ERROR:
+ case SASI_AES_INVALID_KEY_POINTER_ERROR:
+ case SASI_AES_DATA_IN_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case SASI_AES_ILLEGAL_OPERATION_MODE_ERROR:
+ case SASI_AES_KEY_TYPE_NOT_SUPPORTED_ERROR:
+ case SASI_AES_INVALID_ENCRYPT_MODE_ERROR:
+ case SASI_AES_ILLEGAL_PADDING_TYPE_ERROR:
+ case SASI_AES_INCORRECT_PADDING_ERROR:
+ case SASI_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE:
+ case SASI_AES_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR:
+ case SASI_AES_IS_NOT_SUPPORTED:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case SASI_AES_DATA_OUT_BUFFER_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case SASI_AES_DATA_OUT_POINTER_INVALID_ERROR:
+ case SASI_AES_DATA_OUT_SIZE_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case SASI_AES_CTX_SIZES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t params_validate(nrf_crypto_backend_cc310_aes_context_t const * const p_ctx,
+ SaSiAesOperationMode_t * p_mode,
+ nrf_crypto_operation_t operation)
+{
+ ret_code_t ret_val = NRF_SUCCESS;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ *p_mode = SASI_AES_MODE_ECB;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ *p_mode = SASI_AES_MODE_CBC;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ *p_mode = SASI_AES_MODE_CTR;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ *p_mode = SASI_AES_MODE_CBC_MAC;
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ *p_mode = SASI_AES_MODE_CMAC;
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+ break;
+#endif
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+ }
+
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_init(void * const p_context, nrf_crypto_operation_t operation)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ SaSiAesOperationMode_t mode;
+ SaSiAesEncryptMode_t operation_cc310;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(&p_ctx->any.context))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+ if (p_ctx->any.header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128)
+ {
+ ret_val = NRF_ERROR_CRYPTO_KEY_SIZE;
+ goto exit;
+ }
+
+ ret_val = params_validate(p_ctx, &mode, operation);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+
+ if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ operation_cc310 = SASI_AES_DECRYPT;
+ }
+ else if ((operation == NRF_CRYPTO_ENCRYPT) || (operation == NRF_CRYPTO_MAC_CALCULATE))
+ {
+ operation_cc310 = SASI_AES_ENCRYPT;
+ }
+ else
+ {
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ goto exit;
+ }
+ p_ctx->any.backend.operation = operation;
+
+ result = SaSi_AesInit(&p_ctx->any.context,
+ operation_cc310,
+ mode,
+ SASI_AES_PADDING_NONE); /* CC310 does not support padding */
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ bool mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ result = SaSi_AesFree(&p_ctx->any.context);
+ ret_val = result_get(result);
+
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_key_set(void * const p_context, uint8_t * p_key)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ SaSiAesUserKeyData_t key_data;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_key))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ key_data.pKey = p_key;
+ key_data.keySize = (p_ctx->any.header.p_info->key_size) >> 3; // change bits to bytes
+
+ result = SaSi_AesSetKey(&p_ctx->any.context,
+ SASI_AES_USER_KEY,
+ &key_data,
+ sizeof(key_data));
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+static ret_code_t backend_cc310_iv_set(void * const p_context, uint8_t * p_iv)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_iv))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ result = SaSi_AesSetIv(&p_ctx->any.context, p_iv);
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_iv_get(void * const p_context, uint8_t * p_iv)
+{
+ SaSiError_t result;
+ ret_code_t ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_iv))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ result = SaSi_AesGetIv(&p_ctx->any.context, p_iv);
+
+ /* Below code allows to read IV after calling nrf_crypto_aes_finalize */
+ if (result == SASI_AES_ILLEGAL_OPERATION_MODE_ERROR)
+ {
+ if (p_ctx->any.header.init_value == NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE)
+ {
+ memcpy(p_iv, p_ctx->any.backend.iv, NRF_CRYPTO_MBEDTLS_AES_IV_SIZE);
+ ret_val = NRF_SUCCESS;
+ }
+ }
+ else
+ {
+ ret_val = result_get(result);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+#endif
+
+static ret_code_t backend_cc310_update(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t size;
+ size_t offset = 0;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ do
+ {
+ /* CC310 allows only 64kB blocks, operation must be devided */
+ if (data_size > CC310_MAX_LENGTH_DMA_AES_OPERATIONS)
+ {
+ size = CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ data_size -= CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ }
+ else
+ {
+ size = data_size;
+ data_size = 0;
+ }
+
+ cc310_backend_enable();
+
+ if (p_ctx->any.backend.operation == NRF_CRYPTO_MAC_CALCULATE)
+ {
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out);
+ }
+ else
+ {
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out + offset);
+ }
+
+ cc310_backend_disable();
+
+ offset += size;
+ ret_val = result_get(result);
+
+ } while ((data_size > 0) && (ret_val == NRF_SUCCESS));
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t size;
+ size_t offset = 0;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (*p_data_out_size < data_size)
+ {
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ goto exit;
+ }
+
+ /* This function does not support padding */
+ if (((data_size & 0xF) != 0) &&
+ (p_ctx->any.header.p_info->mode != NRF_CRYPTO_AES_MODE_CTR))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ goto exit;
+ }
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ /* CC310 allows only 64kB blocks, operation must be devided */
+ while (data_size > CC310_MAX_LENGTH_DMA_AES_OPERATIONS)
+ {
+ size = CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ data_size -= CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+
+ cc310_backend_enable();
+
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out + offset);
+
+ cc310_backend_disable();
+
+ offset += size;
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ /* Calculate space in the output buffer */
+ *p_data_out_size -= offset;
+
+ cc310_backend_enable();
+
+ result = SaSi_AesFinish(&p_ctx->any.context,
+ data_size,
+ p_data_in + offset,
+ data_size,
+ p_data_out + offset,
+ p_data_out_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ /* update information about size of encrypted data */
+ *p_data_out_size += offset;
+ }
+
+ /* Store IV value in case it will be needed after finalize operation */
+ if ((p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CBC) ||
+ (p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CTR))
+ {
+ result = SaSi_AesGetIv(&p_ctx->any.context, &p_ctx->any.backend.iv[0]);
+ ret_val = result_get(result);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+static ret_code_t backend_cc310_mac_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t size;
+ size_t offset = 0;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ goto exit;
+ }
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ /* This function does not support padding for CBC-MAC */
+ if (((data_size & 0xF) != 0) &&
+ (NRF_CRYPTO_AES_MODE_CBC_MAC == p_ctx->any.header.p_info->mode))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ goto exit;
+ }
+
+ /* CC310 allows only 64kB blocks, operation must be devided */
+ while (data_size > CC310_MAX_LENGTH_DMA_AES_OPERATIONS)
+ {
+ size = CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ data_size -= CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+
+ cc310_backend_enable();
+
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out);
+
+ cc310_backend_disable();
+
+ offset += size;
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ cc310_backend_enable();
+
+ result = SaSi_AesFinish(&p_ctx->any.context,
+ data_size,
+ p_data_in + offset,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ /* update information about size of encrypted data */
+ *p_data_out_size = NRF_CRYPTO_AES_BLOCK_SIZE;
+ }
+
+ /* Store IV value in case it will be needed after finalize operation */
+ if (p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7)
+ {
+ result = SaSi_AesGetIv(&p_ctx->any.context, &p_ctx->any.backend.iv[0]);
+ ret_val = result_get(result);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+static ret_code_t backend_cc310_cbc_mac_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ /* output buffer too small */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ data_size -= msg_ending;
+
+ if (data_size > 0)
+ {
+ ret_val = backend_cc310_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = backend_cc310_mac_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ return ret_val;
+}
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+static ret_code_t backend_cc310_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+ size_t buff_out_size;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ if (p_ctx->any.backend.operation == NRF_CRYPTO_DECRYPT)
+ {
+ ret_val = backend_cc310_finalize(p_context,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+
+ ret_val = padding_pkcs7_remove(p_data_out,
+ p_data_out_size);
+ return ret_val;
+ }
+
+ /* -------------- ENCRYPTION --------------*/
+ data_size -= msg_ending;
+
+ if (*p_data_out_size < (data_size + NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ /* no space for padding */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ if (data_size > 0)
+ {
+ ret_val = backend_cc310_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ buff_out_size = *p_data_out_size - data_size;
+
+ ret_val = backend_cc310_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out + data_size,
+ &buff_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ *p_data_out_size = buff_out_size + data_size;
+
+ /* Store IV value in case it will be needed after finalize operation */
+ if (p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7)
+ {
+ result = SaSi_AesGetIv(&p_ctx->any.context, &p_ctx->any.backend.iv[0]);
+ ret_val = result_get(result);
+ }
+
+ return ret_val;
+}
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_padding_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_padding_finalize
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_cbc_mac_padding_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_mac_finalize
+};
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_AES_BACKEND_CC310)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h
new file mode 100644
index 0000000..e7127a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_AES_H__
+#define CC310_BACKEND_AES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_aes nrf_crypto CC310 backend AES
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief AES functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) || defined(__SDK_DOXYGEN__)
+
+#include "ssi_aes.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aes_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* AES CBC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC)
+#error "Duplicate definition of AES CBC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CBC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CBC_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_aes_ctx_t backend;
+} nrf_crypto_backend_aes_cbc_context_t;
+#endif
+
+/* AES CTR */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CTR)
+#error "Duplicate definition of AES CTR mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CTR_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CTR_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_aes_ctx_t backend;
+} nrf_crypto_backend_aes_ctr_context_t;
+#endif
+
+/* AES ECB */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_ECB)
+#error "Duplicate definition of AES ECB mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_ECB_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_ECB_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend;
+} nrf_crypto_backend_aes_ecb_context_t;
+#endif
+
+
+/* AES CBC_MAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC_MAC)
+#error "Duplicate definition of AES CBC_MAC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CBC_MAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CBC_MAC_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_aes_ctx_t backend;
+} nrf_crypto_backend_aes_cbc_mac_context_t;
+#endif
+
+/* AES CMAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC)
+#error "Duplicate definition of AES CMAC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CMAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CMAC_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend;
+} nrf_crypto_backend_aes_cmac_context_t;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/** @} */
+
+#endif // CC310_BACKEND_AES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c
new file mode 100644
index 0000000..e8e312e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c
@@ -0,0 +1,366 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "crys_aesccm_error.h"
+#include "cc310_backend_aes_aead.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_AES_AEAD)
+
+/**@internal @brief Type declaration of a template suiting all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ CRYS_AESCCM_UserContext_t context;
+ uint8_t key[16]; /**< Only supported key size by CC310 is 128 bit */
+} nrf_crypto_backend_cc310_aes_aead_context_t;
+
+static ret_code_t result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_AESCCM_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_KEY_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_KEY_SIZE;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_TAG_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_NONCE_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR:
+ case CRYS_AESCCM_DATA_IN_SIZE_ILLEGAL:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case CRYS_AESCCM_INVALID_KEY_POINTER_ERROR:
+ case CRYS_AESCCM_ILLEGAL_PARAMETER_PTR_ERROR:
+ case CRYS_AESCCM_DATA_IN_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case CRYS_AESCCM_IS_NOT_SUPPORTED:
+ case CRYS_AESCCM_INVALID_ENCRYPT_MODE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_AESCCM_DATA_OUT_SIZE_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case CRYS_AESCCM_DATA_OUT_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_PARAMETER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case CRYS_AESCCM_CCM_MAC_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+
+ case CRYS_AESCCM_CTX_SIZES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_init(void * const p_context, uint8_t * p_key)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_cc310_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_aead_context_t *)p_context;
+
+ if (!nrfx_is_in_ram(p_ctx))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ }
+ if (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128)
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ switch (p_ctx->header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM)
+ case NRF_CRYPTO_AEAD_MODE_AES_CCM:
+ ret_val = NRF_SUCCESS;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR)
+ case NRF_CRYPTO_AEAD_MODE_AES_CCM_STAR:
+ ret_val = NRF_SUCCESS;
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ memcpy(p_ctx->key, p_key, sizeof(p_ctx->key));
+
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ nrf_crypto_backend_cc310_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_aead_context_t *)p_context;
+
+ memset(&p_ctx->context, 0, sizeof(CRYS_AESCCM_UserContext_t));
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cc310_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+
+{
+ uint32_t mode;
+ CRYSError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ SaSiAesEncryptMode_t operation_cc310;
+ CRYS_AESCCM_Mac_Res_t mac_buffer;
+
+ nrf_crypto_backend_cc310_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_aead_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_adata) && (adata_size > 0))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ /* CC310 supports: CCM & CCM*, where nonce_size must be > 0, so p_nonce must always
+ point to RAM. */
+ if (!nrfx_is_in_ram(p_nonce) ||
+ !nrfx_is_in_ram(p_data_in) ||
+ !nrfx_is_in_ram(p_data_out) ||
+ !nrfx_is_in_ram(p_mac))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ operation_cc310 = SASI_AES_DECRYPT;
+ }
+ else if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ operation_cc310 = SASI_AES_ENCRYPT;
+ }
+ else
+ {
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ goto exit;
+ }
+
+ if (p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_CCM)
+ {
+ mode = CRYS_AESCCM_MODE_CCM;
+
+ /* Allowed MAC size in CCM mode: [4, 6, 8, 10, 12, 14, 16] */
+ if ((mac_size < NRF_CRYPTO_AES_CCM_MAC_MIN) ||
+ (mac_size > NRF_CRYPTO_AES_CCM_MAC_MAX) ||
+ ((mac_size & 0x01) != 0))
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ goto exit;
+ }
+
+ if ((nonce_size < NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN) ||
+ (nonce_size > NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX))
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ goto exit;
+ }
+ }
+ else
+ {
+ mode = CRYS_AESCCM_MODE_STAR;
+
+ /* Allowed MAC size in CCM* mode: [0, 4, 8, 16] */
+ if ((mac_size | NRF_CRYPTO_AES_CCM_STAR_MAC_BITMASK) != NRF_CRYPTO_AES_CCM_STAR_MAC_BITMASK)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ goto exit;
+ }
+
+ /* Allowed nonce size in CCM* mode: [13] */
+ if (nonce_size != NRF_CRYPTO_AES_CCM_STAR_NONCE_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ goto exit;
+ }
+ }
+
+ cc310_backend_enable();
+
+ result = CC_AESCCM_Init(&p_ctx->context,
+ operation_cc310,
+ p_ctx->key,
+ CRYS_AES_Key128BitSize, // the only allowed key size for CC310
+ (uint32_t)adata_size,
+ (uint32_t)data_in_size,
+ p_nonce,
+ nonce_size,
+ mac_size,
+ mode);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+
+ if ((adata_size > 0) && (p_adata != NULL))
+ {
+ cc310_backend_enable();
+
+ result = CRYS_AESCCM_BlockAdata(&p_ctx->context,
+ p_adata,
+ (uint32_t)adata_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ /* CC310 backend always needs 16 bytes buffer for MAC calculation. */
+ memcpy(mac_buffer, p_mac, mac_size);
+
+ cc310_backend_enable();
+
+ result = CRYS_AESCCM_Finish(&p_ctx->context,
+ p_data_in,
+ (uint32_t)data_in_size,
+ p_data_out,
+ mac_buffer,
+ &mac_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+ if (ret_val == NRF_SUCCESS)
+ {
+ memcpy(p_mac, mac_buffer, mac_size);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_star_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM_STAR,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_AES_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h
new file mode 100644
index 0000000..34622d9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_AES_AEAD_H__
+#define CC310_BACKEND_AES_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_aes_aead nrf_crypto CC310 backend AES AEAD
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "crys_aesccm.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_CC310_AES_BACKEND_KEY_SIZE (16)
+
+
+/* AES CCM */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM)
+#error "Duplicate definition of AES CCM mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CCM_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aead frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_AEAD_ENABLED
+#define NRF_CRYPTO_CC310_AES_AEAD_ENABLED 1 // aead backend for cc310 can be compiled
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CCM_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ CRYS_AESCCM_UserContext_t context; /**< AES CCM context internal to CC310. */
+
+ uint8_t key[NRF_CRYPTO_CC310_AES_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_aes_ccm_context_t;
+#endif
+
+/* AES CCM* (CCM STAR) */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM_STAR)
+#error "Duplicate definition of AES CCM* (star) mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CCM_STAR_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aes_aead frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_AEAD_ENABLED
+#define NRF_CRYPTO_CC310_AES_AEAD_ENABLED 1 // aead backend for cc310 can be compiled
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CCM_STAR_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ CRYS_AESCCM_UserContext_t context; /**< AES CCM context internal to CC310. */
+
+ uint8_t key[NRF_CRYPTO_CC310_AES_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_aes_ccm_star_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/** @} */
+
+#endif // CC310_BACKEND_AES_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c
new file mode 100644
index 0000000..16ca026
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <drivers/nrfx_common.h>
+#include <stdbool.h>
+#include "cc310_backend_mutex.h"
+#include "crys_chacha_poly_error.h"
+#include "cc310_backend_chacha_poly_aead.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_CHACHA_POLY_AEAD)
+
+static ret_code_t result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ /*! Invalid Additional data. */
+ case CRYS_CHACHA_POLY_DATA_INVALID_ERROR:
+ case CRYS_CHACHA_POLY_ADATA_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ /*! Illegal encryption mode. */
+ case CRYS_CHACHA_POLY_ENC_MODE_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ /*! Illegal data size. */
+ case CRYS_CHACHA_POLY_DATA_SIZE_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ /*! MAC comparison error. */
+ case CRYS_CHACHA_POLY_MAC_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_init(void * const p_context, uint8_t * p_key)
+{
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+ if (!nrfx_is_in_ram(p_ctx))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ }
+
+ if (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256)
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ memcpy(p_ctx->key, p_key, sizeof(p_ctx->key));
+ return NRF_SUCCESS;
+}
+
+static inline ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cc310_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+
+{
+ CRYSError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ CRYS_CHACHA_EncryptMode_t operation_cc310;
+
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if ((adata_size == 0) || (data_in_size == 0))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ goto exit;
+ }
+
+ if (mac_size != NRF_CRYPTO_CHACHA_POLY_MAC_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ goto exit;
+ }
+
+ if (nonce_size != NRF_CRYPTO_CHACHA_POLY_NONCE_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ goto exit;
+ }
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out) ||
+ !nrfx_is_in_ram(p_mac) || !nrfx_is_in_ram(p_adata) ||
+ !nrfx_is_in_ram(p_nonce))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ operation_cc310 = CRYS_CHACHA_Decrypt;
+ }
+ else if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ operation_cc310 = CRYS_CHACHA_Encrypt;
+ }
+ else
+ {
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ goto exit;
+ }
+
+ cc310_backend_enable();
+
+ result = CRYS_CHACHA_POLY(p_nonce,
+ p_ctx->key,
+ operation_cc310,
+ p_adata,
+ adata_size,
+ p_data_in,
+ data_in_size,
+ p_data_out,
+ (uint32_t *)p_mac);
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+nrf_crypto_aead_info_t const g_nrf_crypto_chacha_poly_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_CHACHA_POLY,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_CHACHA_POLY_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h
new file mode 100644
index 0000000..4c1edf9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_CHACHA_POLY_AEAD_H__
+#define CC310_BACKEND_CHACHA_POLY_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_chacha_poly_aead nrf_crypto CC310 backend CHACHA_POLY AEAD
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief CHACHA_POLY AEAD functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "crys_chacha_poly.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_CC310_CHACHA_POLY_BACKEND_KEY_SIZE (32)
+
+/* CHACHA-POLY */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CHACHA_POLY)
+#error "Duplicate definition of CHACHA-POLY mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_CHACHA_POLY_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aead frontend can be compiled
+#undef NRF_CRYPTO_CC310_CHACHA_POLY_AEAD_ENABLED
+#define NRF_CRYPTO_CC310_CHACHA_POLY_AEAD_ENABLED 1 // aead backend for cc310 can be compiled
+
+/* defines for test purposes */
+#define NRF_CRYPTO_CHACHA_POLY_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+
+ uint8_t key[NRF_CRYPTO_CC310_CHACHA_POLY_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_chacha_poly_context_t;
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/** @} */
+
+#endif // CC310_BACKEND_CHACHA_POLY_AEAD_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c
new file mode 100644
index 0000000..e93230c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c
@@ -0,0 +1,464 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <string.h>
+
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "cc310_backend_ecc.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "crys_ecpki_kg.h"
+#include "crys_ecpki_domain.h"
+#include "crys_ecpki_build.h"
+#include "crys_ecpki_error.h"
+#include "crys_rnd_error.h"
+
+
+#define CC310_UNCOMPRESSED_PUBLIC_KEY_ID_BYTE 0x04 /**< @brief @internal Byte value used by CC310 library to prefix uncompressed public key. */
+
+
+ret_code_t nrf_crypto_backend_cc310_ecc_error_convert(uint32_t crys_error)
+{
+ switch (crys_error)
+ {
+ case CRYS_OK:
+ return NRF_SUCCESS;
+
+ case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+
+ case CRYS_RND_INSTANTIATION_NOT_DONE_ERROR:
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+
+ default:
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+}
+
+
+/** @internal @brief Returns domain value from @ref CRYS_ECPKI_DomainID_t enum based on
+ * value from info structure.
+ *
+ * @param[in] p_info Curve info.
+ * @returns Pointer to CC310 domain.
+ */
+static CRYS_ECPKI_Domain_t const * get_domain(nrf_crypto_ecc_curve_info_t const * p_info)
+{
+ CRYS_ECPKI_DomainID_t domain_id = (CRYS_ECPKI_DomainID_t)(intptr_t)p_info->p_backend_data;
+ const CRYS_ECPKI_Domain_t * domain = CRYS_ECPKI_GetEcDomain(domain_id);
+ return domain;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_ecc_public_key_convert(
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub,
+ CRYS_ECPKI_BUILD_TempData_t * p_temp_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_Domain_t const * p_domain;
+ uint8_t ucompressed_key[NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE + 1];
+ bool mutex_locked;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (p_pub->key_converted)
+ {
+ return NRF_SUCCESS;
+ }
+
+ p_domain = get_domain(p_info);
+
+ // Tell CC310 library that this is raw public key in uncompressed format.
+ ucompressed_key[0] = CC310_UNCOMPRESSED_PUBLIC_KEY_ID_BYTE;
+ memcpy(&ucompressed_key[1], p_pub->key.raw_public_key, p_info->raw_public_key_size);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ if (!mutex_locked)
+ {
+ return NRF_ERROR_CRYPTO_BUSY;
+ }
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECPKI_BuildPublKeyFullCheck(p_domain,
+ ucompressed_key,
+ p_info->raw_public_key_size + 1,
+ &p_pub->key.cc310_public_key,
+ p_temp_data);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ if (result == NRF_SUCCESS)
+ {
+ p_pub->key_converted = true;
+ }
+ else
+ {
+ memcpy(p_pub->key.raw_public_key, &ucompressed_key[1], p_info->raw_public_key_size);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_Domain_t const * p_domain;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_key_pair_generate_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_key_pair_generate_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ p_domain = get_domain(p_prv->header.p_info);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECPKI_GenKeyPair(p_context,
+ nrf_crypto_backend_cc310_rng,
+ p_domain,
+ &p_prv->private_key,
+ &p_pub->key.cc310_public_key,
+ &p_ctx->temp_data,
+ NULL);
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ p_pub->key_converted = true;
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_Domain_t const * p_domain;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ p_domain = get_domain(p_info);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ crys_error = CRYS_ECPKI_BuildPrivKey(p_domain,
+ p_raw_data,
+ p_info->raw_private_key_size,
+ &p_prv->private_key);
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint32_t key_size;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ key_size = p_info->raw_private_key_size;
+
+ crys_error = CRYS_ECPKI_ExportPrivKey(&p_prv->private_key,
+ p_raw_data,
+ &key_size);
+
+ if (key_size != p_info->raw_private_key_size)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ memcpy(p_pub->key.raw_public_key, p_raw_data, p_info->raw_public_key_size);
+ p_pub->key_converted = false;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint8_t ucompressed_key[NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE + 1];
+ uint32_t key_size;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!p_pub->key_converted)
+ {
+ memcpy(p_raw_data, p_pub->key.raw_public_key, p_info->raw_public_key_size);
+ return NRF_SUCCESS;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ if (!mutex_locked)
+ {
+ return NRF_ERROR_CRYPTO_BUSY;
+ }
+
+ key_size = p_info->raw_public_key_size + 1;
+
+ crys_error = CRYS_ECPKI_ExportPublKey(&p_pub->key.cc310_public_key,
+ CRYS_EC_PointUncompressed,
+ ucompressed_key,
+ &key_size);
+
+ cc310_backend_mutex_unlock();
+
+ if ((key_size != p_info->raw_public_key_size + 1)
+ || (ucompressed_key[0] != CC310_UNCOMPRESSED_PUBLIC_KEY_ID_BYTE))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ memcpy(p_raw_data, &ucompressed_key[1], p_info->raw_public_key_size);
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP160R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP160R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP160R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp160r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r2_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP160R2_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP160R2_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP160R2_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp160r2,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp192r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp224r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp256r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp384r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp384r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp521r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp521r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP160K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP160K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP160K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp160k1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp192k1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp224k1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp256k1,
+};
+#endif
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h
new file mode 100644
index 0000000..f9f20e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h
@@ -0,0 +1,548 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_ECC_H__
+#define CC310_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+#include "crys_ecpki_kg.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @internal @brief Common structure holding private key for CC310.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ CRYS_ECPKI_UserPrivKey_t private_key; /**< @internal @brief CC310 specific key representation */
+} nrf_crypto_backend_cc310_ecc_private_key_t;
+
+
+/** @internal @brief Common structure holding public key for CC310.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ bool key_converted; /**< @internal @brief True if key was already converted from raw_public_key to cc310_public_key */
+ union
+ {
+ CRYS_ECPKI_UserPublKey_t cc310_public_key; /**< @internal @brief CC310 specific key representation */
+ uint8_t raw_public_key[132]; /**< @internal @brief raw key representation */
+ } key;
+} nrf_crypto_backend_cc310_ecc_public_key_t;
+
+
+/** @internal @brief Common structure holding context for key pair generation.
+ */
+typedef struct
+{
+ CRYS_ECPKI_KG_TempData_t temp_data; /**< @internal @brief Temporary buffer for CC310 internal storage */
+} nrf_crypto_backend_cc310_key_pair_generate_context_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Convert error code from CC310 to nrf_crypto error code.
+ *
+ * @param[in] crys_error CC310 error code.
+ * @return nrf_crypto error code.
+ */
+ret_code_t nrf_crypto_backend_cc310_ecc_error_convert(uint32_t crys_error);
+
+
+/** @internal @brief Converts public key from raw to CC310 representation if not converted already.
+ *
+ * Data are read from p_pub->key.raw_public_key to stored into p_pub->cc310_public_key.
+ *
+ * @param[in] p_pub Public key to convert.
+ * @param[in] p_temp_data Buffer for temporary data used by CC310 lib.
+ * @return nrf_crypto error code.
+ */
+ret_code_t nrf_crypto_backend_cc310_ecc_public_key_convert(
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub,
+ CRYS_ECPKI_BUILD_TempData_t * p_temp_data);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP160R1)
+#error "More than one backend enabled for secp160r1 (NIST 160-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP160R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp160r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp160r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp160r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp160r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp160r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp160r1_private_key_free NULL
+#define nrf_crypto_backend_secp160r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP160R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp160r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp160r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp160r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp160r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP160R2)
+#error "More than one backend enabled for secp160r2 (NIST 160-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP160R2_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r2_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp160r2_public_key_calculate NULL
+#define nrf_crypto_backend_secp160r2_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp160r2_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp160r2_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp160r2_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp160r2_private_key_free NULL
+#define nrf_crypto_backend_secp160r2_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP160R2_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R2_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp160r2_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp160r2_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp160r2_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp160r2_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192R1)
+#error "More than one backend enabled for secp192r1 (NIST 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp192r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp192r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp192r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp192r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp192r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp192r1_private_key_free NULL
+#define nrf_crypto_backend_secp192r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp192r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp192r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp224r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp224r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp224r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp224r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp224r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp224r1_private_key_free NULL
+#define nrf_crypto_backend_secp224r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp224r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp256r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp256r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp256r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP384R1)
+#error "More than one backend enabled for secp384r1 (NIST 384-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp384r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp384r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp384r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp384r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp384r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp384r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp384r1_private_key_free NULL
+#define nrf_crypto_backend_secp384r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp384r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp384r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp384r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp384r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP521R1)
+#error "More than one backend enabled for secp521r1 (NIST 521-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp521r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp521r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp521r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp521r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp521r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp521r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp521r1_private_key_free NULL
+#define nrf_crypto_backend_secp521r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp521r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp521r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp521r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp521r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP160K1)
+#error "More than one backend enabled for secp160k1 (Koblitz 160-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP160K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp160k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp160k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp160k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp160k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp160k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp160k1_private_key_free NULL
+#define nrf_crypto_backend_secp160k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP160K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp160k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp160k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp160k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp160k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192K1)
+#error "More than one backend enabled for secp192k1 (Koblitz 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp192k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp192k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp192k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp192k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp192k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp192k1_private_key_free NULL
+#define nrf_crypto_backend_secp192k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp192k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp192k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp192k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224K1)
+#error "More than one backend enabled for secp224k1 (Koblitz 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp224k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp224k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp224k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp224k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp224k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp224k1_private_key_free NULL
+#define nrf_crypto_backend_secp224k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp224k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp224k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp224k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256K1)
+#error "More than one backend enabled for secp256k1 (Koblitz 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp256k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp256k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp256k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp256k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp256k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp256k1_private_key_free NULL
+#define nrf_crypto_backend_secp256k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp256k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp256k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#endif // CC310_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c
new file mode 100644
index 0000000..48c2e5c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <string.h>
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_mem.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_ecdh.h"
+
+
+ret_code_t nrf_crypto_backend_cc310_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint32_t shared_secret_size;
+ uint8_t aligned_buffer[(NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE + 3) & ~3];
+ uint8_t * p_output_buffer;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_ecdh_compute_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_ecdh_compute_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ result = nrf_crypto_backend_cc310_ecc_public_key_convert(p_pub, &p_ctx->key_build_temp_data);
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ shared_secret_size = p_info->raw_private_key_size;
+
+ if ((shared_secret_size & 3) != 0) // Check if shared_secret_size is word aligned
+ {
+ shared_secret_size = (shared_secret_size + 3) & ~3;
+ p_output_buffer = &aligned_buffer[0];
+ }
+ else
+ {
+ p_output_buffer = p_shared_secret;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ if (!mutex_locked)
+ {
+ return NRF_ERROR_CRYPTO_BUSY;
+ }
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECDH_SVDP_DH(&p_pub->key.cc310_public_key,
+ &p_prv->private_key,
+ p_output_buffer,
+ &shared_secret_size,
+ &p_ctx->temp_data);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ if (p_output_buffer != p_shared_secret)
+ {
+ //lint -save -e645 (Symbol 'aligned_buffer' may not have been initialized)
+ memcpy(p_shared_secret,
+ &aligned_buffer[3 - ((p_info->raw_private_key_size + 3) & 3)], // Bytes at the beginning that were added during padding are now skipped
+ p_info->raw_private_key_size);
+ //lint -restore
+ }
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h
new file mode 100644
index 0000000..0fe1dc4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_ECDH_H__
+#define CC310_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "crys_ecpki_dh.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Common structure holding context for ECDH.
+ */
+typedef union
+{
+ CRYS_ECDH_TempData_t temp_data; /**< @internal @brief Temporary buffer for CC310 internal storage */
+ CRYS_ECPKI_BUILD_TempData_t key_build_temp_data; /**< @internal @brief Temporary buffer for CC310 public key build */
+} nrf_crypto_backend_cc310_ecdh_compute_context_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP160R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp160r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r2_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP160R2_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp160r2_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp384r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp384r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp521r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp521r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP160K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp160k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp192k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp224k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#endif // CC310_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c
new file mode 100644
index 0000000..69a1a86
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <string.h>
+#include "ssi_pal_types.h"
+#include "ssi_pal_mem.h"
+#include "sns_silib.h"
+#include "crys_rnd.h"
+#include "crys_ecpki_ecdsa.h"
+#include "crys_ecpki_error.h"
+#include "crys_kdf_error.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#include "nrf_crypto_ecdsa.h"
+#include "cc310_backend_ecdsa.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_mutex.h"
+
+
+#define CC310_SHA1_DIGEST_SIZE (160 / 8) /**< @internal @brief Digest size of SHA-1 */
+#define CC310_SHA224_DIGEST_SIZE (224 / 8) /**< @internal @brief Digest size of SHA-224 */
+#define CC310_SHA256_DIGEST_SIZE (256 / 8) /**< @internal @brief Digest size of SHA-256 */
+#define CC310_SHA384_DIGEST_SIZE (384 / 8) /**< @internal @brief Digest size of SHA-384 */
+#define CC310_SHA512_DIGEST_SIZE (512 / 8) /**< @internal @brief Digest size of SHA-512 */
+
+
+/** @internal @brief Returns enum value of @ref CRYS_ECPKI_HASH_OpMode_t based on provided hash size.
+ *
+ * @param[in] data_size Hash size
+ * @return Value from @ref CRYS_ECPKI_HASH_OpMode_t or CRYS_ECPKI_HASH_OpModeLast if
+ * cannot find implemented hash with provided size.
+ */
+static CRYS_ECPKI_HASH_OpMode_t hash_mode_from_size(uint32_t data_size)
+{
+ CRYS_ECPKI_HASH_OpMode_t hash_mode;
+
+ switch (data_size)
+ {
+ case CC310_SHA1_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA1_mode;
+ break;
+
+ case CC310_SHA224_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA224_mode;
+ break;
+
+ case CC310_SHA256_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA256_mode;
+ break;
+
+ case CC310_SHA384_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA384_mode;
+ break;
+
+ case CC310_SHA512_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA512_mode;
+ break;
+
+ default:
+ hash_mode = CRYS_ECPKI_HASH_OpModeLast;
+ break;
+ }
+
+ return hash_mode;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint32_t signature_size;
+ CRYS_ECPKI_HASH_OpMode_t hash_mode = hash_mode_from_size(data_size);
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_sign_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_sign_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (hash_mode == CRYS_ECPKI_HASH_OpModeLast)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ signature_size = p_info->raw_public_key_size;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECDSA_Sign(p_context,
+ nrf_crypto_backend_cc310_rng,
+ &p_ctx->user_context,
+ &p_prv->private_key,
+ hash_mode,
+ (uint8_t *)p_data,
+ data_size,
+ p_signature,
+ &signature_size);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+
+ if (result == NRF_SUCCESS && signature_size != p_info->raw_public_key_size)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_HASH_OpMode_t hash_mode = hash_mode_from_size(data_size);
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_verify_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_verify_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ result = nrf_crypto_backend_cc310_ecc_public_key_convert(p_pub, &p_ctx->key_build_temp_data);
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ if (hash_mode == CRYS_ECPKI_HASH_OpModeLast)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECDSA_Verify(&p_ctx->user_context,
+ &p_pub->key.cc310_public_key,
+ hash_mode,
+ (uint8_t *)p_signature,
+ p_info->raw_public_key_size,
+ (uint8_t *)p_data,
+ data_size);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h
new file mode 100644
index 0000000..b57c18e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_ECDSA_H__
+#define CC310_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#include "crys_ecpki_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Common structure holding context for ECDSA sign.
+ */
+typedef struct
+{
+ CRYS_ECDSA_SignUserContext_t user_context; /**< @internal @brief Temporary buffer for CC310 internal storage */
+} nrf_crypto_backend_cc310_sign_context_t;
+
+
+/** @internal @brief Common structure holding context for ECDSA verify.
+ */
+typedef union
+{
+ CRYS_ECDSA_VerifyUserContext_t user_context; /**< @internal @brief Temporary buffer for CC310 internal storage */
+ CRYS_ECPKI_BUILD_TempData_t key_build_temp_data; /**< @internal @brief Temporary buffer for CC310 public key build */
+} nrf_crypto_backend_cc310_verify_context_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+#define NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp160r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp160r1_verify_context_t;
+#define nrf_crypto_backend_secp160r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp160r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+#define NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp160r2_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp160r2_verify_context_t;
+#define nrf_crypto_backend_secp160r2_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp160r2_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp192r1_verify_context_t;
+#define nrf_crypto_backend_secp192r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp192r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp224r1_verify_context_t;
+#define nrf_crypto_backend_secp224r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp224r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp256r1_verify_context_t;
+#define nrf_crypto_backend_secp256r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp256r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+#define NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp384r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp384r1_verify_context_t;
+#define nrf_crypto_backend_secp384r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp384r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+#define NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp521r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp521r1_verify_context_t;
+#define nrf_crypto_backend_secp521r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp521r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+#define NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp160k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp160k1_verify_context_t;
+#define nrf_crypto_backend_secp160k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp160k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+#define NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp192k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp192k1_verify_context_t;
+#define nrf_crypto_backend_secp192k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp192k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+#define NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp224k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp224k1_verify_context_t;
+#define nrf_crypto_backend_secp224k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp224k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp256k1_verify_context_t;
+#define nrf_crypto_backend_secp256k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp256k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#endif // CC310_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c
new file mode 100644
index 0000000..b1f91e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c
@@ -0,0 +1,311 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf.h"
+#include "cc310_backend_hash.h"
+#include "crys_hash.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+#include <drivers/nrfx_common.h>
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+static ret_code_t hash_result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ // May be added to specialized errors for hash.
+ case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+
+ case CRYS_HASH_IS_NOT_SUPPORTED:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+static ret_code_t cc310_backend_hash_sha256_init(void * const p_context)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+ CRYS_HASH_OperationMode_t hash_mode = CRYS_HASH_SHA256_mode;
+
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ crys_error = CRYS_HASH_Init(p_backend_context, hash_mode);
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+ size_t cur_len;
+ size_t len_left = size;
+ uint8_t const * p_cur = p_data;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ // Data in flash could lead to silently calculating wrong Hash.
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ // If the input is larger than CC310_MAX_LENGTH_DMA_OPERATIONS, split into smaller
+ do
+ {
+ cur_len = (len_left > CC310_MAX_LENGTH_DMA_OPERATIONS) ?
+ CC310_MAX_LENGTH_DMA_OPERATIONS : len_left;
+
+ crys_error = CRYS_HASH_Update(p_backend_context, (uint8_t *)p_cur, cur_len);
+
+ len_left -= cur_len;
+ p_cur += cur_len;
+
+ } while (crys_error == CRYS_OK && len_left > 0);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+ CRYS_HASH_Result_t * p_int_digest = (CRYS_HASH_Result_t *)p_digest;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * )p_context)->context);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ // Do the hash finalize calculation
+ cc310_backend_enable();
+
+ crys_error = CRYS_HASH_Finish(p_backend_context, *p_int_digest);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+ }
+
+ return ret_val;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = cc310_backend_hash_sha256_init,
+ .update_fn = cc310_backend_hash_sha256_update,
+ .finalize_fn = cc310_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+// SHA-512 does not use CC310 hardware and therefore will not use a mutex lock
+
+static ret_code_t cc310_backend_hash_sha512_init(void * p_context)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+ CRYS_HASH_OperationMode_t hash_mode = CRYS_HASH_SHA512_mode;
+
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t * ) p_context)->context);
+
+ crys_error = CRYS_HASH_Init(p_backend_context, hash_mode);
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha512_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ // Data in flash could lead to silently calculating wrong Hash.
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ crys_error = CRYS_HASH_Update(p_backend_context, (uint8_t *)p_data, size);
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha512_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ CRYS_HASH_Result_t * p_int_digest = (CRYS_HASH_Result_t *)p_digest;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *) p_context)->context);
+
+ crys_error = CRYS_HASH_Finish(p_backend_context, *p_int_digest);
+ ret_val = hash_result_get(crys_error);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA512;
+ }
+
+ return ret_val;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info =
+{
+ .init_fn = cc310_backend_hash_sha512_init,
+ .update_fn = cc310_backend_hash_sha512_update,
+ .finalize_fn = cc310_backend_hash_sha512_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha512_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA512
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h
new file mode 100644
index 0000000..3da4dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_HASH_H__
+#define CC310_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_hash nrf_crypto CC310 backend hash
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Hash functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+#include "crys_hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Flag that SHA-256 is enabled in backend
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**@internal @brief nrf_crypto_hash context for SHA-256 in nrf_crypto CC310 backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ CRYS_HASHUserContext_t context; /**< Hash context internal to CC310. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-512
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+#error "Duplicate definition of SHA-512. More than one backend enabled");
+#endif
+
+// Flag that SHA-512 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA512_ENABLED 1
+
+
+/**@internal @brief nrf_crypto_hash context for SHA-512 in nrf_crypto CC310 backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ CRYS_HASHUserContext_t context; /**< Hash context internal to CC310. */
+} nrf_crypto_backend_hash_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/**@} */
+
+#endif // CC310_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c
new file mode 100644
index 0000000..2e909f9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c
@@ -0,0 +1,273 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "sdk_common.h"
+#include "nrf_log.h"
+#include "nrf_crypto_hmac_shared.h"
+#include "cc310_backend_hmac.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include <drivers/nrfx_common.h>
+#include "crys_hmac.h"
+#include "crys_hmac_defs.h"
+#include "crys_hmac_error.h"
+#include "crys_hash.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+
+static ret_code_t result_get(CRYSError_t err_code)
+{
+ ret_code_t ret_val;
+
+ switch (err_code)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_HMAC_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_HMAC_USER_CONTEXT_CORRUPTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ case CRYS_HMAC_DATA_IN_POINTER_INVALID_ERROR:
+ case CRYS_HMAC_INVALID_KEY_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case CRYS_HMAC_INVALID_RESULT_BUFFER_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case CRYS_HMAC_ILLEGAL_PARAMS_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case CRYS_HMAC_UNVALID_KEY_SIZE_ERROR:
+ case CRYS_HMAC_DATA_SIZE_ILLEGAL:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case CRYS_HMAC_ILLEGAL_OPERATION_MODE_ERROR:
+ case CRYS_HMAC_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
+ case CRYS_HMAC_IS_NOT_SUPPORTED:
+ case CRYS_HMAC_CTX_SIZES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hmac_init(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ CRYSError_t err_code;
+ CRYS_HASH_OperationMode_t hash_mode;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+
+ nrf_crypto_backend_cc310_hmac_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_hmac_context_t *)p_context;
+
+ switch (p_ctx->header.p_info->type)
+ {
+ case NRF_CRYPTO_HMAC_SHA256_TYPE:
+ {
+ hash_mode = CRYS_HASH_SHA256_mode;
+ } break;
+ case NRF_CRYPTO_HMAC_SHA512_TYPE:
+ {
+ hash_mode = CRYS_HASH_SHA512_mode;
+ } break;
+ default:
+ {
+ NRF_LOG_ERROR("Hash algorithm not supported by CC310 backend wrapper");
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+ }
+
+ // Key in flash could lead to silently calculating wrong HMAC.
+ VERIFY_TRUE(nrfx_is_in_ram(p_key), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_HMAC_Init(&p_ctx->crys_context, hash_mode, (uint8_t *)p_key, key_size);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = result_get(err_code);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hmac_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t cur_len;
+ size_t len_left = size;
+ uint8_t const * p_cur = p_data;
+
+ nrf_crypto_backend_cc310_hmac_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_hmac_context_t *)p_context;
+
+ // Data in flash could lead to silently calculating wrong HMAC.
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ // If the input is larger than CC310_MAX_LENGTH_DMA_OPERATIONS, split into smaller
+ do
+ {
+ cur_len = (len_left > CC310_MAX_LENGTH_DMA_OPERATIONS) ?
+ CC310_MAX_LENGTH_DMA_OPERATIONS : len_left;
+
+ err_code = CRYS_HMAC_Update(&p_ctx->crys_context, (uint8_t *)p_cur, cur_len);
+
+ len_left -= cur_len;
+ p_cur += cur_len;
+
+ } while (err_code == CRYS_OK && len_left > 0);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = result_get(err_code);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hmac_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_hmac_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_hmac_context_t *)p_context;
+
+ // Set the digest length to 0 so that this is used in case of any error.
+ *p_size = 0;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_HMAC_Finish(&p_ctx->crys_context, p_ctx->crys_result);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = result_get(err_code);
+ if (err_code != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ memcpy(p_digest, p_ctx->crys_result, *p_size);
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+// Information structure for HMAC SHA256 using CC310 backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info =
+{
+ .init_fn = cc310_backend_hmac_init,
+ .update_fn = cc310_backend_hmac_update,
+ .finalize_fn = cc310_backend_hmac_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha256_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA256_TYPE,
+};
+
+#endif // NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+
+// Information structure for HMAC SHA512 using CC310 backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info =
+{
+ .init_fn = cc310_backend_hmac_init,
+ .update_fn = cc310_backend_hmac_update,
+ .finalize_fn = cc310_backend_hmac_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha512_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA512_TYPE,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h
new file mode 100644
index 0000000..ea065f1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_HMAC_H__
+#define CC310_BACKEND_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_hmac CC310 backend for HMAC
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Backend wrapper for CryptoCell (CC310). None of these types should be used directly by the
+ * application.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) && \
+ ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512) )
+
+#include "nrf_crypto_hmac_shared.h"
+#include "crys_hmac.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NRF_CRYPTO_HMAC_ENABLED
+#define NRF_CRYPTO_HMAC_ENABLED 1
+
+
+/**
+ * @internal @brief Internal context object used by the CC310 backend wrapper.
+ *
+ * @details The same type is used for all variants (hash types).
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha256_context_t or
+ * @ref nrf_crypto_backend_hmac_sha512_context_t instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context header.
+ CRYS_HMACUserContext_t crys_context; //!< CC310 context object.
+ CRYS_HASH_Result_t crys_result; //!< Temporary result buffer needed as CC310 always requires a result buffer of 64 bytes, even when actual result is smaller.
+} nrf_crypto_backend_cc310_hmac_context_t;
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA256)
+#error "Duplicate definition of HMAC SHA-256. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_HMAC_SHA256_ENABLED 1
+
+/**
+ * @internal @brief Context for HMAC SHA256 using CC310 backend.
+ */
+typedef nrf_crypto_backend_cc310_hmac_context_t nrf_crypto_backend_hmac_sha256_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA512)
+#error "Duplicate definition of HMAC SHA-512. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_HMAC_SHA512_ENABLED 1
+
+/**
+ * @internal @brief Context for HMAC SHA512 using CC310 backend.
+ */
+typedef nrf_crypto_backend_cc310_hmac_context_t nrf_crypto_backend_hmac_sha512_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) && ( NRF_MODULE_ENABLED((NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512) )
+
+/**@} */
+
+#endif // CC310_BACKEND_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c
new file mode 100644
index 0000000..d930436
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf.h"
+#include "nrf_crypto_init.h"
+#include "cc310_backend_shared.h"
+#include "sns_silib.h"
+#include "cc310_backend_mutex.h"
+#include "nrf_crypto_rng.h"
+
+/**@internal @brief Function to enable CC310 (in HW)
+ */
+void cc310_backend_enable(void);
+
+
+/**@internal @brief Function to disable CC310 (in HW)
+ */
+void cc310_backend_disable(void);
+
+static uint32_t init_result_get(uint32_t crys_error)
+{
+ uint32_t ret_val = NRF_ERROR_INTERNAL;
+ switch (crys_error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+static ret_code_t cc310_backend_init(void)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+
+ cc310_backend_mutex_init();
+
+ // Enable the CC310 HW.
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Initialize the CC310 run-time library
+ crys_error = SaSi_LibInit();
+
+ // Shut down CC310 after initialization.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ ret_val = init_result_get(crys_error);
+ VERIFY_SUCCESS(ret_val);
+
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ ret_val = nrf_crypto_rng_init(NULL, NULL);
+ VERIFY_SUCCESS(ret_val);
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ // Do nothing
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_uninit(void)
+{
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ uint32_t ret_val;
+ ret_val = nrf_crypto_rng_init(NULL, NULL);
+ VERIFY_SUCCESS(ret_val);
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ // Do nothing
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED
+
+ // Initialize the CC310 HW to do shutdown.
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ SaSi_LibFini();
+
+ // Shut down CC310 after shutdown.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const cc310_backend) =
+{
+ .init_fn = cc310_backend_init,
+ .uninit_fn = cc310_backend_uninit,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c
new file mode 100644
index 0000000..f383251
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "cc310_backend_mutex.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+nrf_mtx_t g_cc310_mutex;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h
new file mode 100644
index 0000000..3cd6241
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_MUTEX_H__
+#define CC310_BACKEND_MUTEX_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_mutex nrf_crypto CC310 backend mutex.
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Mutex control for the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+#include "nrf_mtx.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern nrf_mtx_t g_cc310_mutex;
+
+__STATIC_INLINE void cc310_backend_mutex_init(void);
+__STATIC_INLINE bool cc310_backend_mutex_trylock(void);
+__STATIC_INLINE void cc310_backend_mutex_unlock(void);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+/**@internal @brief Function initializing CC310 mutex.
+ *
+ * This function _must_ be called before other mutex operations.
+ */
+__STATIC_INLINE void cc310_backend_mutex_init(void)
+{
+ nrf_mtx_init(&g_cc310_mutex);
+}
+
+/**@internal @brief Function try to lock a CC310 mutex.
+ *
+ * @return true if lock was acquired, false if not.
+ */
+__STATIC_INLINE bool cc310_backend_mutex_trylock(void)
+{
+ return nrf_mtx_trylock(&g_cc310_mutex);
+}
+
+
+/**@internal @brief Unlock a CC310 mutex.
+ *
+ * This function _must_ only be called when holding the lock. Unlocking a mutex which you do not
+ * hold will give undefined behavior.
+ *
+ */
+__STATIC_INLINE void cc310_backend_mutex_unlock(void)
+{
+ nrf_mtx_unlock(&g_cc310_mutex);
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+/** @} */
+
+#endif // CC310_BACKEND_MUTEX_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c
new file mode 100644
index 0000000..25fd96e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c
@@ -0,0 +1,272 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+
+#include "nrf_crypto_error.h"
+#include "nrf_log.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_rng.h"
+#include "crys_rnd.h"
+#include "crys_rnd_error.h"
+#include "cc310_backend_shared.h"
+
+static ret_code_t result_get(CRYSError_t err_code)
+{
+ ret_code_t ret_val;
+
+ switch (err_code)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_RND_ILLEGAL_PARAMETER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case CRYS_RND_INIT_FAILED:
+ case CRYS_RND_STARTUP_FAILED:
+ case CRYS_RND_INSTANTIATION_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_RNG_INIT_FAILED;
+ break;
+
+ case CRYS_RND_IS_NOT_SUPPORTED:
+ case CRYS_RND_CAN_NOT_GENERATE_RAND_IN_RANGE:
+ case CRYS_RND_TRNG_KAT_NOT_SUPPORTED_ERROR:
+ case CRYS_RND_SRAM_NOT_SUPPORTED_ERROR:
+ case CRYS_RND_OPERATION_IS_NOT_SUPPORTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_RND_DATA_OUT_POINTER_INVALID_ERROR:
+ case CRYS_RND_VECTOR_OUT_PTR_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case CRYS_RND_ADDITIONAL_INPUT_BUFFER_NULL:
+ case CRYS_RND_WORK_BUFFER_PTR_INVALID_ERROR:
+ case CRYS_RND_ILLEGAL_DATA_PTR_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case CRYS_RND_DATA_SIZE_OVERFLOW_ERROR:
+ case CRYS_RND_ADDITIONAL_INPUT_SIZE_ERROR:
+ case CRYS_RND_ILLEGAL_DATA_SIZE_ERROR:
+ case CRYS_RND_MAX_VECTOR_IS_TOO_SMALL_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case CRYS_RND_ILLEGAL_AES_KEY_SIZE_ERROR:
+ case CRYS_RND_VECTOR_OUT_SIZE_ERROR:
+ case CRYS_RND_VECTOR_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case CRYS_RND_CONTEXT_PTR_INVALID_ERROR:
+ case CRYS_RND_STATE_PTR_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_RND_INSTANTIATION_NOT_DONE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ case CRYS_RND_RESEED_COUNTER_OVERFLOW_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED;
+ break;
+
+ case CRYS_RND_CPRNG_TEST_FAIL_ERROR:
+ case CRYS_RND_TRNG_LOSS_SAMPLES_ERROR:
+ case CRYS_RND_TRNG_TIME_EXCEED_ERROR:
+ case CRYS_RND_TRNG_LOSS_SAMPLES_AND_TIME_EXCEED_ERROR:
+ case CRYS_RND_IS_KAT_MODE_ERROR:
+ case CRYS_RND_STATE_VALIDATION_TAG_ERROR:
+ case CRYS_RND_GEN_VECTOR_FUNC_ERROR:
+ case CRYS_RND_TRNG_ERRORS_ERROR:
+ case CRYS_RND_KAT_DATA_PARAMS_ERROR:
+ case CRYS_RND_AES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context,
+ void * const p_temp_buffer)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ CRYS_RND_WorkBuff_t * p_work_buffer = (CRYS_RND_WorkBuff_t *)p_temp_buffer;
+ nrf_crypto_backend_rng_context_t * p_ctx = (nrf_crypto_backend_rng_context_t *)p_context;
+
+ // Save time by not reinitializing an already valid CC310 RNG context.
+ // (Useful for example in case the context was stored in retained memory during system OFF.)
+ if (p_ctx->header.init_value == NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE)
+ {
+ return NRF_SUCCESS;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_RndInit(&p_ctx->crys_rnd_state, p_work_buffer);
+ ret_val = result_get(err_code);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ CRYS_RND_State_t * p_crys_rnd_state =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state;
+
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_RND_UnInstantiation(p_crys_rnd_state);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(err_code);
+
+ cc310_backend_mutex_unlock();
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ CRYS_RND_State_t * p_crys_rnd_state =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state;
+
+ if (use_mutex)
+ {
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+ }
+
+ cc310_backend_enable();
+
+ err_code = CRYS_RND_GenerateVector(p_crys_rnd_state, size, p_target);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(err_code);
+
+ if (use_mutex)
+ {
+ cc310_backend_mutex_unlock();
+ }
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val = NRF_SUCCESS;
+ CRYS_RND_WorkBuff_t * p_work_buffer = (CRYS_RND_WorkBuff_t *)p_temp_buffer;
+ CRYS_RND_State_t * p_crys_rnd_state =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state;
+
+ VERIFY_TRUE(size <= CRYS_RND_ADDITINAL_INPUT_MAX_SIZE_WORDS, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ VERIFY_TRUE((size & 0x3) == 0, NRF_ERROR_CRYPTO_INTERNAL);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ if (size > 0)
+ {
+ err_code = CRYS_RND_AddAdditionalInput(p_crys_rnd_state, p_input_data, size);
+ ret_val = result_get(err_code);
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ err_code = CRYS_RND_Reseeding(p_crys_rnd_state, p_work_buffer);
+ ret_val = result_get(err_code);
+
+exit:
+ cc310_backend_disable();
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h
new file mode 100644
index 0000000..ab1806a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_RNG_H__
+#define CC310_BACKEND_RNG_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_rng nRF Crypto CC310 RNG backend
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief RNG functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+
+#include "nrf_crypto_rng_shared.h"
+#include "crys_rnd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#error "More than one RNG backend enabled."
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#define NRF_CRYPTO_RNG_ENABLED 1
+
+
+/**
+ * @internal @brief Internal context for CC310 RNG.
+ */
+typedef struct
+{
+ nrf_crypto_rng_internal_context_t header; //!< Internal common context header.
+ CRYS_RND_State_t crys_rnd_state; //!< CC310 RNG context
+} nrf_crypto_backend_rng_context_t;
+
+
+/**
+ * @internal @brief Temporary work buffer needed during initialization of the CC310 backend.
+ */
+typedef CRYS_RND_WorkBuff_t nrf_crypto_backend_rng_temp_buffer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/**@} */
+
+#endif // CC310_BACKEND_RNG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c
new file mode 100644
index 0000000..d5f2351
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf.h"
+#include "cc310_backend_shared.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_rng.h"
+#include "crys_rnd_error.h"
+#include "nrf_crypto_shared.h"
+#include "cc310_backend_shared.h"
+
+
+static uint32_t m_use_count = 0;
+
+void cc310_backend_enable(void)
+{
+ m_use_count++;
+
+ if (m_use_count == 1)
+ {
+ // Enable the CryptoCell hardware
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Enable the CryptoCell IRQ
+ NVIC_EnableIRQ(CRYPTOCELL_IRQn);
+ }
+}
+
+void cc310_backend_disable(void)
+{
+ m_use_count--;
+
+ // If no more users. Disable HW/IRQ
+ if (m_use_count == 0)
+ {
+ // Disable the CryptoCell hardware
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ // Disable the CryptoCell IRQ
+ NVIC_DisableIRQ(CRYPTOCELL_IRQn);
+ }
+}
+
+
+uint32_t nrf_crypto_backend_cc310_rng(void * p_state, uint16_t size, uint8_t * p_data)
+{
+#if defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 1)
+
+ ret_code_t result = nrf_crypto_rng_vector_generate_no_mutex(p_data, (size_t)size);
+ if (result == NRF_SUCCESS)
+ {
+ return CRYS_OK;
+ }
+ else if (result == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED)
+ {
+ return CRYS_RND_INSTANTIATION_NOT_DONE_ERROR;
+ }
+ else
+ {
+ return CRYS_RND_IS_NOT_SUPPORTED;
+ }
+
+#elif defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 0)
+
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_ENABLED
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h
new file mode 100644
index 0000000..56fae0e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BACKEND_SHARED_H__
+#define CC310_BACKEND_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_shared nrf_crypto CC310 backend shared
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Shared functionality for the nrf_crypto CC310 backend.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Macro definition for largest possible input data on CC310 DMA. */
+#define CC310_MAX_LENGTH_DMA_OPERATIONS (0xFFFF)
+#define CC310_MAX_LENGTH_DMA_AES_OPERATIONS (0xFFF0)
+
+
+/**@internal @brief Function to enable CC310 (in HW)
+ */
+void cc310_backend_enable(void);
+
+
+/**@internal @brief Function to disable CC310 (in HW)
+ */
+void cc310_backend_disable(void);
+
+
+/**@internal @brief Function to pass to CC310 library API as random number generator. It uses
+ * nrf_crypto libary frontend API to generate random number.
+ * @param[in,out] p_state Unused. Required by CC310 library API.
+ * @param[in] size Number of bytes in generated vector.
+ * @param[out] p_data Place where generated bytes will be written.
+ */
+uint32_t nrf_crypto_backend_cc310_rng(void * p_state, uint16_t size, uint8_t * p_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // CC310_BACKEND_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c
new file mode 100644
index 0000000..cec2ec7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include <string.h>
+
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_shared.h"
+#include "cc310_bl_backend_ecc.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN)
+#define ENDIAN_MEM_COPY nrf_crypto_internal_swap_endian
+#else
+#define ENDIAN_MEM_COPY memcpy
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+ret_code_t nrf_crypto_backend_secp224r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_secp224r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp224r1_public_key_t *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_pub->public_key.x[0],
+ &p_raw_data[0],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_pub->public_key.y[0],
+ &p_raw_data[NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_secp224r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_secp224r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp224r1_public_key_t const *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_raw_data[0],
+ &p_pub->public_key.x[0],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_raw_data[NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE],
+ &p_pub->public_key.y[0],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+nrf_crypto_ecc_curve_info_t const g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp224r1_public_key_t),
+ .private_key_size = 0,
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+ret_code_t nrf_crypto_backend_secp256r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_pub->public_key.x[0],
+ &p_raw_data[0],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_pub->public_key.y[0],
+ &p_raw_data[NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_secp256r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t const *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_raw_data[0],
+ &p_pub->public_key.x[0],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_raw_data[NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE],
+ &p_pub->public_key.y[0],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+nrf_crypto_ecc_curve_info_t const g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256r1_public_key_t),
+ .private_key_size = 0,
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h
new file mode 100644
index 0000000..381c642
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_ECC_H__
+#define CC310_BL_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf_crypto_ecc_shared.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp224r1.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp256r1.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ nrf_cc310_bl_ecc_public_key_secp224r1_t public_key; /**< @internal @brief CC310_BL specific key representation */
+} nrf_crypto_backend_secp224r1_public_key_t;
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp224r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp224r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+// Dummy and empty definitions for unused symbols
+#define nrf_crypto_backend_secp224r1_key_pair_generate NULL
+#define nrf_crypto_backend_secp224r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp224r1_private_key_from_raw NULL
+#define nrf_crypto_backend_secp224r1_private_key_to_raw NULL
+#define nrf_crypto_backend_secp224r1_private_key_free NULL
+#define nrf_crypto_backend_secp224r1_public_key_free NULL
+
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+typedef uint32_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ nrf_cc310_bl_ecc_public_key_secp256r1_t public_key; /**< @internal @brief CC310_BL specific key representation */
+} nrf_crypto_backend_secp256r1_public_key_t;
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp256r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp256r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+// Dummy and empty definitions for unused symbols
+#define nrf_crypto_backend_secp256r1_key_pair_generate NULL
+#define nrf_crypto_backend_secp256r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp256r1_private_key_from_raw NULL
+#define nrf_crypto_backend_secp256r1_private_key_to_raw NULL
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+typedef uint32_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#endif // CC310_BL_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h
new file mode 100644
index 0000000..ce52194
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_ECDH_H__
+#define CC310_BL_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+#define nrf_crypto_backend_secp224r1_ecdh_compute NULL
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+#define nrf_crypto_backend_secp256r1_ecdh_compute NULL
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#endif // CC310_BL_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c
new file mode 100644
index 0000000..5b99a83
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c
@@ -0,0 +1,267 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include <string.h>
+#include "app_util.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_shared.h"
+#include "cc310_bl_backend_ecdsa.h"
+#include "cc310_bl_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "crys_ecpki_error.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+static ret_code_t crys_error_to_ret_code(CRYSError_t crys_error)
+{
+ switch (crys_error)
+ {
+ case CRYS_OK:
+ return NRF_SUCCESS;
+
+ case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_CRYPTO_INTERNAL;
+}
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp224r1_t, r) == 0,
+ "Offset of r in nrf_cc310_bl_ecc_signature_secp224r1_t is unexpected");
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp224r1_t, s) ==
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ "Offset of s in nrf_cc310_bl_ecc_signature_secp224r1_t is unexpected");
+
+
+ret_code_t nrf_crypto_backend_secp224r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+
+ nrf_crypto_backend_secp224r1_verify_context_t * p_ctx =
+ (nrf_crypto_backend_secp224r1_verify_context_t *)p_context;
+
+ nrf_crypto_backend_secp224r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp224r1_public_key_t *)p_public_key;
+
+ p_ctx->user_context.init_val = NRF_CC310_BL_ECDSA_CONTEXT_INITIALIZED;
+
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 1)
+
+ size_t hash_size = MIN(data_size, NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+ uint8_t * p_hash_and_sig_le =
+ NRF_CRYPTO_ALLOC(hash_size + 2 * NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ if (p_hash_and_sig_le == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+
+ nrf_crypto_internal_swap_endian(p_hash_and_sig_le, p_data, hash_size);
+
+ nrf_crypto_internal_double_swap_endian(&p_hash_and_sig_le[hash_size],
+ p_signature,
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp224r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp224r1_t const *)&p_hash_and_sig_le[hash_size],
+ p_hash_and_sig_le,
+ hash_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ NRF_CRYPTO_FREE(p_hash_and_sig_le);
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 0)
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp224r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp224r1_t const *)p_signature,
+ p_data,
+ data_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+#else
+
+ #error NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED define not found in sdk_config.h Inalid sdk_config.h!
+
+#endif
+
+ result = crys_error_to_ret_code(crys_error);
+
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp256r1_t, r) == 0,
+ "Offset of r in nrf_cc310_bl_ecc_signature_secp256r1_t is unexpected");
+
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp256r1_t, s) ==
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ "Offset of s in nrf_cc310_bl_ecc_signature_secp256r1_t is unexpected");
+
+
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+
+
+ nrf_crypto_backend_secp256r1_verify_context_t * p_ctx =
+ (nrf_crypto_backend_secp256r1_verify_context_t *)p_context;
+
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ p_ctx->user_context.init_val = NRF_CC310_BL_ECDSA_CONTEXT_INITIALIZED;
+
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 1)
+
+ uint8_t hash_le[NRF_CRYPTO_HASH_SIZE_SHA256];
+ uint8_t signature_le[NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE * 2];
+ size_t hash_size = MIN(data_size, NRF_CRYPTO_HASH_SIZE_SHA256);
+
+ nrf_crypto_internal_swap_endian(hash_le, p_data, hash_size);
+
+ nrf_crypto_internal_double_swap_endian(signature_le,
+ p_signature,
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp256r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp256r1_t const *)signature_le,
+ hash_le,
+ hash_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 0)
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp256r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp256r1_t const *)p_signature,
+ p_data,
+ data_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+#else
+
+ #error NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED define not found in sdk_config.h. Invalid sdk_config.file!
+
+#endif
+
+ result = crys_error_to_ret_code(crys_error);
+
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h
new file mode 100644
index 0000000..f75a035
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_ECDSA_H__
+#define CC310_BL_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp224r1.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp256r1.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+/** @internal @brief Common structure holding context for ECDSA verify.
+ */
+typedef struct
+{
+ nrf_cc310_bl_ecdsa_verify_context_secp224r1_t user_context; /**< @internal @brief Temporary buffer for CC310_BL internal storage */
+} nrf_crypto_backend_secp224r1_verify_context_t;
+
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_secp224r1_verify_context_t)
+
+ret_code_t nrf_crypto_backend_secp224r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+// Dummy and empty definitions for unused symbols
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp224r1_sign_context_t;
+#define nrf_crypto_backend_secp224r1_sign NULL
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+/** @internal @brief Common structure holding context for ECDSA verify.
+ */
+typedef struct
+{
+ nrf_cc310_bl_ecdsa_verify_context_secp256r1_t user_context; /**< @internal @brief Temporary buffer for CC310_BL internal storage */
+} nrf_crypto_backend_secp256r1_verify_context_t;
+
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_secp256r1_verify_context_t)
+
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+// Dummy and empty definitions for unused symbols
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+#define nrf_crypto_backend_secp256r1_sign NULL
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#endif // CC310_BL_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c
new file mode 100644
index 0000000..59010f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c
@@ -0,0 +1,281 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf.h"
+#include "cc310_bl_backend_hash.h"
+#include "cc310_bl_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+#include "nrf_cc310_bl_hash_sha256.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+#include <drivers/nrfx_common.h>
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER)
+
+__ALIGN(4) static uint8_t m_hash_buffer[NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE];
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER)
+
+
+static ret_code_t hash_result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ // May be added to specialized errors for hash.
+ case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+
+ case CRYS_HASH_IS_NOT_SUPPORTED:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_bl_backend_hash_sha256_init(void * const p_context)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ nrf_cc310_bl_hash_context_sha256_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ crys_error = nrf_cc310_bl_hash_sha256_init(p_backend_context);
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static uint32_t cc310_bl_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ uint32_t cur_size;
+ uint32_t size_left;
+ uint8_t * p_cur;
+ bool mutex_locked;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ nrf_cc310_bl_hash_context_sha256_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ p_cur = (uint8_t *)p_data;
+ size_left = size;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+#if defined (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED == 1)
+
+ do
+ {
+ // Copy a block from FLASH to RAM for use in CC310
+ cur_size = (size_left > NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE) ?
+ NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE : size_left;
+
+ // Copy from FLASH to ram
+ memcpy(m_hash_buffer, p_cur, cur_size);
+
+ // Update the hash with current input.
+ crys_error = nrf_cc310_bl_hash_sha256_update(p_backend_context, m_hash_buffer, cur_size);
+
+ size_left -= cur_size;
+ p_cur += cur_size;
+
+ } while(crys_error == SASI_OK && size_left > 0);
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED == 0)
+
+ // Verify that the data is in RAM (required for CC310 hashing)
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ do
+ {
+ // Get the largest block that can sent to the CC310 through DMA
+ cur_size = (size_left > CC310_MAX_LENGTH_DMA_OPERATIONS) ?
+ CC310_MAX_LENGTH_DMA_OPERATIONS : size_left;
+
+ crys_error = nrf_cc310_bl_hash_sha256_update(p_backend_context, p_cur, cur_size);
+
+ size_left -= cur_size;
+ p_cur += cur_size;
+ } while(crys_error == SASI_OK && size_left > 0);
+
+#else
+
+ UNUSED_PARAMETER(p_backend_context);
+ UNUSED_PARAMETER(cur_size);
+ UNUSED_PARAMETER(size_left);
+ UNUSED_PARAMETER(p_cur);
+
+ #warning NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static uint32_t cc310_bl_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ nrf_cc310_bl_hash_context_sha256_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * )p_context)->context);
+
+ nrf_cc310_bl_hash_digest_sha256_t * p_int_digest
+ = (nrf_cc310_bl_hash_digest_sha256_t *)p_digest;
+
+ if (NRF_CRYPTO_HASH_SIZE_SHA256 > *p_digest_size)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ // Do the hash finalize calculation
+ crys_error = nrf_cc310_bl_hash_sha256_finalize(p_backend_context, p_int_digest);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+ }
+
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 1)
+
+ nrf_crypto_internal_swap_endian_in_place(p_digest, NRF_CRYPTO_HASH_SIZE_SHA256);
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 0)
+
+ // Do nothing
+
+#else
+
+ #warning NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+
+ return ret_val;
+}
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = cc310_bl_backend_hash_sha256_init,
+ .update_fn = cc310_bl_backend_hash_sha256_update,
+ .finalize_fn = cc310_bl_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h
new file mode 100644
index 0000000..6882c04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_HASH_H__
+#define CC310_BL_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_bl_backend_hash nrf_crypto CC310_BL backend hash
+ * @{
+ * @ingroup nrf_crypto_cc310_bl_backend
+ *
+ * @brief Hash functionality provided by the nrf_crypto CC310_BL backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+#include "nrf_cc310_bl_hash_sha256.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Flag that SHA-256 is enabled in backend
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**@internal @brief nrf_crypto_hash context for SHA-256 in nrf_crypto CC310_BL backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ nrf_cc310_bl_hash_context_sha256_t context; /**< Hash context internal to CC310_BL. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+/**@} */
+
+#endif // CC310_BL_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c
new file mode 100644
index 0000000..38f440c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_error.h"
+
+#include "cc310_bl_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "sns_silib.h"
+#include "nrf_cc310_bl_init.h"
+
+/**@brief Mutex to ensure single access to nrf_cc310_bl resources */
+nrf_mtx_t g_cc310_mutex;
+
+static uint32_t init_result_get(uint32_t crys_error)
+{
+ uint32_t ret_val = NRF_ERROR_INTERNAL;
+ switch (crys_error)
+ {
+ case SA_SILIB_RET_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case SA_SILIB_RET_EINVAL_HW_VERSION:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_bl_backend_init(void)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+
+ cc310_backend_mutex_init();
+
+ // Enable the CC310 HW.
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Initialize the CC310_BL run-time library
+ crys_error = nrf_cc310_bl_init();
+
+ // Disable the CC310 HW after initialization.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ ret_val = init_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_bl_backend_uninit(void)
+{
+ // Disable the CC310 HW.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const cc310_bl_backend) =
+{
+ .init_fn = cc310_bl_backend_init,
+ .uninit_fn = cc310_bl_backend_uninit
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c
new file mode 100644
index 0000000..520a116
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf.h"
+#include "cc310_bl_backend_shared.h"
+#include "nrf_crypto_error.h"
+
+
+void cc310_bl_backend_enable(void)
+{
+ // Enable the cryptocell hardware
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Enable the CryptoCell IRQ
+ NVIC_EnableIRQ(CRYPTOCELL_IRQn);
+}
+
+
+void cc310_bl_backend_disable(void)
+{
+ // Enable the cryptocell hardware
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ // Disable the CryptoCell IRQ
+ NVIC_DisableIRQ(CRYPTOCELL_IRQn);
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h
new file mode 100644
index 0000000..db7c933
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_SHARED_H__
+#define CC310_BL_BACKEND_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_bl_backend_shared nrf_crypto CC310_BL backend shared
+ * @{
+ * @ingroup nrf_crypto_cc310_bl_backend
+ *
+ * @brief Shared functionality for the nrf_crypto CC310_BL backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@internal @brief Function to enable CC310 (in HW)
+ */
+void cc310_bl_backend_enable(void);
+
+
+/**@internal @brief Function to disable CC310 (in HW)
+ */
+void cc310_bl_backend_disable(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+/**@} */
+
+#endif // CC310_BL_BACKEND_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c
new file mode 100644
index 0000000..23b3cb6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "cifra_backend_aes_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CIFRA_AES_AEAD)
+
+/**@internal @brief Type declaration of a template matching all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ cf_aes_context context;
+} nrf_crypto_backend_cifra_aes_aead_context_t;
+
+
+static ret_code_t result_get(int error)
+{
+ switch (error)
+ {
+ case 0:
+ return NRF_SUCCESS;
+
+ case 1:
+ return NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+
+ default:
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+}
+
+static ret_code_t backend_cifra_init(void * const p_context, uint8_t * p_key)
+{
+ nrf_crypto_backend_cifra_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cifra_aes_aead_context_t *)p_context;
+
+ if ((p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_192) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256))
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ VERIFY_TRUE((p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_EAX),
+ NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ cf_aes_init(&p_ctx->context,
+ p_key,
+ (p_ctx->header.p_info->key_size)>>3); // >>3: changes bits to bytes
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t backend_cifra_uninit(void * const p_context)
+{
+ nrf_crypto_backend_cifra_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cifra_aes_aead_context_t *)p_context;
+
+ cf_aes_finish(&p_ctx->context);
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cifra_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_cifra_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cifra_aes_aead_context_t *)p_context;
+
+ ret_val = NRF_SUCCESS;
+
+ /* EAX mode allows following mac size: [1 ... 16] */
+ if ((mac_size < 1) || (mac_size > NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ cf_eax_encrypt(&cf_aes,
+ &p_ctx->context,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_data_out,
+ p_mac,
+ mac_size);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = cf_eax_decrypt(&cf_aes,
+ &p_ctx->context,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_mac,
+ mac_size,
+ p_data_out);
+ ret_val = result_get(result);
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA_AES_EAX)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_eax_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_EAX,
+
+ .init_fn = backend_cifra_init,
+ .uninit_fn = backend_cifra_uninit,
+ .crypt_fn = backend_cifra_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_eax_192_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_EAX,
+
+ .init_fn = backend_cifra_init,
+ .uninit_fn = backend_cifra_uninit,
+ .crypt_fn = backend_cifra_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_eax_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_EAX,
+
+ .init_fn = backend_cifra_init,
+ .uninit_fn = backend_cifra_uninit,
+ .crypt_fn = backend_cifra_crypt
+};
+#endif
+
+#endif // MODULE_ENABLED(NRF_CRYPTO_AES_CCM_BACKEND_MBEDTLS)
+#endif // MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h
new file mode 100644
index 0000000..d0575ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef CIFRA_BACKEND_AES_AEAD_H__
+#define CIFRA_BACKEND_AES_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cifra_backend_aes_aead nrf_crypto Cifra backend AES AEAD
+ * @{
+ * @ingroup nrf_crypto_cifra_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto Cifra backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA)
+
+#include "modes.h"
+#include "cifra_eax_aes.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AES EAX */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA_AES_EAX)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_EAX)
+#error "Duplicate definition of AES EAX mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_EAX_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aes_aead frontend can be compiled
+#undef NRF_CRYPTO_CIFRA_AES_AEAD_ENABLED
+#define NRF_CRYPTO_CIFRA_AES_AEAD_ENABLED 1 // aes_aead backend cifra can be compiled
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_EAX_128_ENABLED 1
+#define NRF_CRYPTO_AES_EAX_192_ENABLED 1
+#define NRF_CRYPTO_AES_EAX_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ cf_aes_context context; /**< AES EAX context internal to Cifra. */
+} nrf_crypto_backend_aes_eax_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA)
+
+/** @} */
+
+#endif // CIFRA_BACKEND_AES_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c
new file mode 100644
index 0000000..9433471
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c
@@ -0,0 +1,1213 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+/*lint -save -e????*/
+#include "mbedtls/md.h"
+#include "mbedtls/aes.h"
+#include "mbedtls/cipher.h"
+/*lint -restore*/
+#include "nrf_crypto_error.h"
+#include "mbedtls_backend_aes.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES)
+
+/* macro changing bits to bytes */
+#define BITS_TO_BYTES(bits) ((bits)>>3)
+#define BACKEND_ERROR_CHECK(error) \
+ do { \
+ if ((error) != 0) \
+ { \
+ return result_get((error)); \
+ } \
+ } while (0);
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ uint32_t context[1]; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_mbedtls_aes_any_context_t;
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef union
+{
+ nrf_crypto_backend_mbedtls_aes_any_context_t any; /**< Common for all contexts. */
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ nrf_crypto_backend_aes_ecb_context_t ecb;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ nrf_crypto_backend_aes_cbc_context_t cbc;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ nrf_crypto_backend_aes_ctr_context_t ctr;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ nrf_crypto_backend_aes_cfb_context_t cfb;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ nrf_crypto_backend_aes_cbc_mac_context_t cbc_mac;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ nrf_crypto_backend_aes_cmac_context_t cmac;
+#endif
+} nrf_crypto_backend_mbedtls_aes_context_t;
+
+
+static ret_code_t result_get(int error)
+{
+ ret_code_t ret_val;
+ switch (error)
+ {
+ case 0:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+static ret_code_t backend_cmac_init(nrf_crypto_backend_aes_cmac_context_t * const p_cmac_ctx)
+{
+ int error;
+
+ mbedtls_cipher_type_t cipher_type;
+ mbedtls_cipher_info_t const * p_cipher_info;
+
+ mbedtls_cipher_init(&p_cmac_ctx->context);
+
+ switch (p_cmac_ctx->header.p_info->key_size)
+ {
+ case NRF_CRYPTO_KEY_SIZE_128:
+ cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
+ break;
+
+ case NRF_CRYPTO_KEY_SIZE_192:
+ cipher_type = MBEDTLS_CIPHER_AES_192_ECB;
+ break;
+
+ case NRF_CRYPTO_KEY_SIZE_256:
+ cipher_type = MBEDTLS_CIPHER_AES_256_ECB;
+ break;
+
+ default:
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+
+ p_cipher_info = mbedtls_cipher_info_from_type(cipher_type);
+
+ if (p_cipher_info == NULL)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ error = mbedtls_cipher_setup(&p_cmac_ctx->context, p_cipher_info);
+ BACKEND_ERROR_CHECK(error);
+
+ return NRF_SUCCESS;
+}
+#endif
+
+static ret_code_t backend_mbedtls_init(void * const p_context, nrf_crypto_operation_t operation)
+{
+ ret_code_t ret_val = NRF_SUCCESS;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->key_size)
+ {
+ case NRF_CRYPTO_KEY_SIZE_128:
+ case NRF_CRYPTO_KEY_SIZE_192:
+ case NRF_CRYPTO_KEY_SIZE_256:
+ break;
+
+ default:
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->cbc.backend, 0, sizeof(p_ctx->cbc.backend));
+
+ mbedtls_aes_init(&p_ctx->cbc.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->ctr.backend, 0, sizeof(p_ctx->ctr.backend));
+
+ mbedtls_aes_init(&p_ctx->ctr.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->cfb.backend, 0, sizeof(p_ctx->cfb.backend));
+
+ mbedtls_aes_init(&p_ctx->cfb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->ecb.backend, 0, sizeof(p_ctx->ecb.backend));
+
+ mbedtls_aes_init(&p_ctx->ecb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->cbc_mac.backend, 0, sizeof(p_ctx->cbc_mac.backend));
+
+ mbedtls_aes_init(&p_ctx->cbc_mac.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+
+ ret_val = backend_cmac_init(&p_ctx->cmac);
+ break;
+#endif
+ default:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+ }
+
+ p_ctx->any.backend.operation = operation;
+
+ return ret_val;
+}
+
+static ret_code_t backend_mbedtls_uninit(void * const p_context)
+{
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ mbedtls_aes_free(&p_ctx->cbc.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ mbedtls_aes_free(&p_ctx->ctr.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ mbedtls_aes_free(&p_ctx->cfb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ mbedtls_aes_free(&p_ctx->ecb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ mbedtls_aes_free(&p_ctx->cbc_mac.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ mbedtls_cipher_free(&p_ctx->cmac.context);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_key_set(void * const p_context, uint8_t * p_key)
+{
+ int error;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ if (p_ctx->cbc.backend.operation == NRF_CRYPTO_ENCRYPT)
+ {
+ error = mbedtls_aes_setkey_enc(&p_ctx->cbc.context,
+ (uint8_t const *)p_key,
+ p_ctx->cbc.header.p_info->key_size);
+ }
+ else
+ {
+ error = mbedtls_aes_setkey_dec(&p_ctx->cbc.context,
+ (uint8_t const *)p_key,
+ p_ctx->cbc.header.p_info->key_size);
+ }
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ /* Due to the nature of CFB / CTR, you should use the same key schedule for both
+ encryption and decryption.*/
+ error = mbedtls_aes_setkey_enc(&p_ctx->ctr.context,
+ (uint8_t const *)p_key,
+ p_ctx->ctr.header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ /* Due to the nature of CFB / CTR, you should use the same key schedule for both
+ encryption and decryption.*/
+ error = mbedtls_aes_setkey_enc(&p_ctx->cfb.context,
+ (uint8_t const *)p_key,
+ p_ctx->cfb.header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ if (p_ctx->ecb.backend.operation == NRF_CRYPTO_ENCRYPT)
+ {
+ error = mbedtls_aes_setkey_enc(&p_ctx->ecb.context,
+ (uint8_t const *)p_key,
+ p_ctx->ecb.header.p_info->key_size);
+ }
+ else
+ {
+ error = mbedtls_aes_setkey_dec(&p_ctx->ecb.context,
+ (uint8_t const *)p_key,
+ p_ctx->ecb.header.p_info->key_size);
+ }
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ error = mbedtls_aes_setkey_enc(&p_ctx->cbc_mac.context,
+ (uint8_t const *)p_key,
+ p_ctx->cbc_mac.header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ error = mbedtls_cipher_cmac_starts(&p_ctx->cmac.context,
+ p_key,
+ p_ctx->cmac.header.p_info->key_size);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ ret_val = result_get(error);
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+static ret_code_t backend_mbedtls_iv_set(void * const p_context, uint8_t * p_iv)
+{
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ memcpy(&p_ctx->any.backend.iv[0], p_iv, sizeof(p_ctx->any.backend.iv));
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_iv_get(void * const p_context, uint8_t * p_iv)
+{
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ memcpy(p_iv, p_ctx->any.backend.iv, sizeof(p_ctx->any.backend.iv));
+
+ return NRF_SUCCESS;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+/* Function extending mbedtls_aes_crypt_ecb functionality. It allows to process more than 1
+ data block. It is returning MBEDTLS error type. */
+static int backend_mbedtls_ecb_crypt(nrf_crypto_backend_aes_ecb_context_t * const p_ctx,
+ uint8_t * p_text_in,
+ uint8_t * p_text_out,
+ size_t text_size)
+{
+ int error = 0;
+ size_t crypted_text = 0;
+
+ if ((text_size & 0x0F) != 0)
+ {
+ return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+ }
+
+ while (crypted_text < text_size)
+ {
+ error = mbedtls_aes_crypt_ecb(&p_ctx->context,
+ (int)p_ctx->backend.operation,
+ p_text_in + crypted_text,
+ p_text_out + crypted_text);
+ if (error != 0)
+ {
+ break;
+ }
+ crypted_text += NRF_CRYPTO_AES_BLOCK_SIZE;
+ }
+
+ return error;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+static int backend_mbedtls_cbc_mac_update(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ int error = 0;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ for (size_t i = 0; i < data_size; i += NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ error = mbedtls_aes_crypt_cbc(&p_ctx->cbc_mac.context,
+ MBEDTLS_AES_ENCRYPT,
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_ctx->cbc_mac.backend.iv,
+ (uint8_t const *)p_data_in + i,
+ p_data_out);
+ if (error != 0)
+ {
+ return error;
+ }
+ }
+
+ return error;
+}
+
+static ret_code_t backend_mbedtls_cbc_mac_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ int error;
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ /* this function does not support padding */
+ if ((data_size & 0xF) != 0)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ error = backend_mbedtls_cbc_mac_update(p_context, p_data_in, data_size, p_data_out);
+ BACKEND_ERROR_CHECK(error);
+
+ *p_data_out_size = NRF_CRYPTO_AES_BLOCK_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_cbc_mac_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ /* output buffer too small */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ data_size -= msg_ending;
+
+ if (data_size > 0)
+ {
+ ret_val = backend_mbedtls_cbc_mac_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = backend_mbedtls_cbc_mac_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ return ret_val;
+}
+#endif
+
+static ret_code_t backend_mbedtls_update(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ int error;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ error = mbedtls_aes_crypt_cbc(&p_ctx->cbc.context,
+ (int)p_ctx->cbc.backend.operation,
+ data_size,
+ p_ctx->cbc.backend.iv,
+ (uint8_t const *)p_data_in,
+ p_data_out);
+ break;
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ {
+ size_t nc_off = 0;
+ uint8_t stream_block[NRF_CRYPTO_AES_BLOCK_SIZE];
+
+ error = mbedtls_aes_crypt_ctr(&p_ctx->ctr.context,
+ data_size,
+ &nc_off,
+ p_ctx->ctr.backend.iv,
+ stream_block,
+ (uint8_t const *)p_data_in,
+ p_data_out);
+ break;
+ }
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ error = mbedtls_aes_crypt_cfb8(&p_ctx->cfb.context,
+ (int)p_ctx->cfb.backend.operation,
+ data_size,
+ p_ctx->cfb.backend.iv,
+ (uint8_t const *)p_data_in,
+ p_data_out);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ error = backend_mbedtls_ecb_crypt(&p_ctx->ecb, p_data_in, p_data_out, data_size);
+ break;
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ error = backend_mbedtls_cbc_mac_update(p_context, p_data_in, data_size, p_data_out);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ error = mbedtls_cipher_cmac_update(&p_ctx->cmac.context,
+ p_data_in,
+ data_size);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+ BACKEND_ERROR_CHECK(error);
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ if (*p_data_out_size < data_size)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ /* data is not multiple of 16 bytes */
+ if ((data_size & 0x0F) != 0)
+ {
+ if ((p_ctx->any.header.p_info->mode != NRF_CRYPTO_AES_MODE_CTR) &&
+ (p_ctx->any.header.p_info->mode != NRF_CRYPTO_AES_MODE_CFB))
+ {
+ /* There are separate handlers for AES modes with padding and for MAC modes. */
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+ }
+
+ ret_val = backend_mbedtls_update(p_context, p_data_in, data_size, p_data_out);
+ VERIFY_SUCCESS(ret_val);
+
+ *p_data_out_size = data_size;
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+static ret_code_t backend_mbedtls_cmac_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ int error;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ error = mbedtls_cipher_cmac_update(&p_ctx->cmac.context, p_data_in, data_size);
+ BACKEND_ERROR_CHECK(error);
+
+ error = mbedtls_cipher_cmac_finish(&p_ctx->cmac.context, p_data_out);
+ BACKEND_ERROR_CHECK(error);
+
+ *p_data_out_size = NRF_CRYPTO_AES_BLOCK_SIZE;
+
+ return NRF_SUCCESS;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+static ret_code_t backend_mbedtls_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ size_t buff_out_size;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ if (p_ctx->any.backend.operation == NRF_CRYPTO_DECRYPT)
+ {
+ ret_val = backend_mbedtls_finalize(p_context,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = padding_pkcs7_remove(p_data_out,
+ p_data_out_size);
+ return ret_val;
+ }
+
+ /* -------------- ENCRYPTION --------------*/
+ data_size -= msg_ending;
+
+ if (*p_data_out_size < (data_size + NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ /* no space for padding */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ if (data_size > 0)
+ {
+ /* Encrypt 16 byte blocks */
+ ret_val = backend_mbedtls_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ buff_out_size = *p_data_out_size - data_size;
+
+ ret_val = backend_mbedtls_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out + data_size,
+ &buff_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ *p_data_out_size = buff_out_size + data_size;
+
+ return ret_val;
+}
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_192_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_256_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+#endif
+
+// CFB
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cfb_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CFB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cfb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cfb_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CFB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cfb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cfb_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CFB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cfb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_192_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_256_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+#endif
+
+
+// CBC MAC
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_192_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_256_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_padding_finalize
+};
+
+#endif
+
+// CMAC
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cmac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cmac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cmac_finalize
+};
+#endif
+
+#endif // #if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES)
+#endif // MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h
new file mode 100644
index 0000000..3813eb3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_AES_H__
+#define MBEDTLS_BACKEND_AES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_aes nrf_crypto mbed TLS backend AES
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief AES functionality provided by the nrf_crypto mbed TLS backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/*lint -save -e????*/
+#include "mbedtls/aes.h"
+#include "mbedtls/cmac.h"
+#include "mbedtls/platform.h"
+/*lint -restore*/
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aes_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AES CBC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC)
+#error "Duplicate definition of AES CBC mode. More than one backend enabled");
+#endif
+/* Flag that AES CBC is enabled in backend */
+#define NRF_CRYPTO_AES_CBC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CBC_128_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_192_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_cbc_context_t;
+#endif
+
+
+/* AES CTR */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CTR)
+#error "Duplicate definition of AES CTR mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CTR_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CTR_128_ENABLED 1
+#define NRF_CRYPTO_AES_CTR_192_ENABLED 1
+#define NRF_CRYPTO_AES_CTR_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_ctr_context_t;
+#endif
+
+/* AES CFB */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CFB)
+#error "Duplicate definition of AES CFB mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CFB_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CFB_128_ENABLED 1
+#define NRF_CRYPTO_AES_CFB_192_ENABLED 1
+#define NRF_CRYPTO_AES_CFB_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_cfb_context_t;
+#endif
+
+/* AES ECB */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_ECB)
+#error "Duplicate definition of AES ECB mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_ECB_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_ECB_128_ENABLED 1
+#define NRF_CRYPTO_AES_ECB_192_ENABLED 1
+#define NRF_CRYPTO_AES_ECB_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_ecb_context_t;
+#endif
+
+
+/* AES CBC MAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC_MAC)
+#error "Duplicate definition of AES CBC MAC mode. More than one backend enabled");
+#endif
+/* Flag that AES CBC MAC is enabled in backend */
+#define NRF_CRYPTO_AES_CBC_MAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CBC_MAC_128_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_MAC_192_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_MAC_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_cbc_mac_context_t;
+#endif
+
+
+/* AES CMAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC)
+#error "Duplicate definition of AES CMAC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CMAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CMAC_128_ENABLED 1
+#define NRF_CRYPTO_AES_CMAC_192_ENABLED 1
+#define NRF_CRYPTO_AES_CMAC_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_cipher_context_t context; /**< AES context internal to mbedtls. */
+} nrf_crypto_backend_aes_cmac_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/** @} */
+
+#endif // MBEDTLS_BACKEND_AES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c
new file mode 100644
index 0000000..eb0319e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c
@@ -0,0 +1,384 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "mbedtls_backend_aes_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES_AEAD)
+
+/**@internal @brief Type declaration of a template suiting all possible context sizes
+ * for this backend.
+ */
+typedef union
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ nrf_crypto_backend_aes_ccm_context_t ccm;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ nrf_crypto_backend_aes_gcm_context_t gcm;
+#endif
+} nrf_crypto_backend_mbedtls_aes_aead_context_t;
+
+
+static ret_code_t result_get(int error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case 0:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ case MBEDTLS_ERR_CCM_BAD_INPUT:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case MBEDTLS_ERR_CCM_AUTH_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ case MBEDTLS_ERR_GCM_BAD_INPUT:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case MBEDTLS_ERR_GCM_AUTH_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+#endif
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t backend_mbedtls_init(void * const p_context, uint8_t * p_key)
+{
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ if ((p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_192) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256))
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ switch (p_ctx->header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ case NRF_CRYPTO_AEAD_MODE_AES_CCM:
+ mbedtls_ccm_init(&p_ctx->ccm.context);
+
+ result = mbedtls_ccm_setkey(&p_ctx->ccm.context,
+ MBEDTLS_CIPHER_ID_AES,
+ p_key,
+ p_ctx->header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ case NRF_CRYPTO_AEAD_MODE_AES_GCM:
+ mbedtls_gcm_init(&p_ctx->gcm.context);
+
+ result = mbedtls_gcm_setkey(&p_ctx->gcm.context,
+ MBEDTLS_CIPHER_ID_AES,
+ p_key,
+ p_ctx->header.p_info->key_size);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ if (result != 0)
+ {
+ ret_val = result_get(result);
+ return ret_val;
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_uninit(void * const p_context)
+{
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ if (p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_CCM)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ mbedtls_ccm_free(&p_ctx->ccm.context);
+#endif
+ }
+ else
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ mbedtls_gcm_free(&p_ctx->gcm.context);
+#endif
+ }
+
+ return NRF_SUCCESS;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+static ret_code_t backend_mbedtls_ccm_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ /* CCM mode allows following MAC sizes: [4, 6, 8, 10, 12, 14, 16] */
+ if ((mac_size < NRF_CRYPTO_AES_CCM_MAC_MIN) || (mac_size > NRF_CRYPTO_AES_CCM_MAC_MAX) ||
+ ((mac_size & 0x01) != 0))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if ((nonce_size < NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN) ||
+ (nonce_size > NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ result = mbedtls_ccm_encrypt_and_tag(&p_ctx->ccm.context,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ p_data_out,
+ p_mac,
+ (size_t)mac_size);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = mbedtls_ccm_auth_decrypt(&p_ctx->ccm.context,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ p_data_out,
+ p_mac,
+ (size_t)mac_size);
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ ret_val = result_get(result);
+
+ return ret_val;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+static ret_code_t backend_mbedtls_gcm_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ /* GCM allows following MAC size: [4 ... 16] */
+ if ((mac_size < NRF_CRYPTO_AES_GCM_MAC_MIN) || (mac_size > NRF_CRYPTO_AES_GCM_MAC_MAX))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ result = mbedtls_gcm_crypt_and_tag(&p_ctx->gcm.context,
+ MBEDTLS_GCM_ENCRYPT,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ p_data_out,
+ (size_t)mac_size,
+ p_mac);
+ ret_val = result_get(result);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = mbedtls_gcm_auth_decrypt(&p_ctx->gcm.context,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_mac,
+ (size_t)mac_size,
+ p_data_in,
+ p_data_out);
+ ret_val = result_get(result);
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ return ret_val;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_ccm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_192_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_ccm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_ccm_crypt
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_gcm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_192_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_gcm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_gcm_crypt
+};
+#endif
+
+#endif // MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES_AEAD)
+#endif // MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h
new file mode 100644
index 0000000..05f24f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_AES_AEAD_H__
+#define MBEDTLS_BACKEND_AES_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_aes_aead nrf_crypto mbed TLS backend AES AEAD
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto mbed TLS backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+/*lint -save -e????*/
+#include "mbedtls/ccm.h"
+#include "mbedtls/gcm.h"
+#include "mbedtls/platform.h"
+/*lint -restore*/
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AES CCM */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM)
+#error "Duplicate definition of AES CCM mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CCM_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1
+#undef NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CCM_128_ENABLED 1
+#define NRF_CRYPTO_AES_CCM_192_ENABLED 1
+#define NRF_CRYPTO_AES_CCM_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ mbedtls_ccm_context context; /**< AES CCM context internal to mbed TLS. */
+} nrf_crypto_backend_aes_ccm_context_t;
+#endif
+
+/* AES GCM */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_GCM)
+#error "Duplicate definition of AES GCM mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_GCM_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1
+#undef NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_GCM_128_ENABLED 1
+#define NRF_CRYPTO_AES_GCM_192_ENABLED 1
+#define NRF_CRYPTO_AES_GCM_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ mbedtls_gcm_context context; /**< AES GCM context internal to mbed TLS. */
+} nrf_crypto_backend_aes_gcm_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/** @} */
+
+#endif // MBEDTLS_BACKEND_AES_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c
new file mode 100644
index 0000000..a69ab7c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c
@@ -0,0 +1,531 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_assert.h"
+#include "mbedtls_backend_ecc.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+#include "mbedtls/bignum.h"
+/*lint -restore*/
+
+
+bool nrf_crypto_backend_mbedtls_ecc_group_load(
+ mbedtls_ecp_group * p_group,
+ struct nrf_crypto_ecc_curve_info_s const * p_info)
+{
+ int result;
+
+ mbedtls_ecp_group_init(p_group);
+ result = mbedtls_ecp_group_load(p_group,
+ (mbedtls_ecp_group_id)(intptr_t)p_info->p_backend_data);
+
+ if (result != 0)
+ {
+ return false;
+ }
+ return true;
+}
+
+
+int nrf_crypto_backend_mbedtls_ecc_mbedtls_rng(void * p_param, unsigned char * p_data, size_t size)
+{
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+ ret_code_t result;
+
+ result = nrf_crypto_rng_vector_generate(p_data, size);
+
+ if (result != NRF_SUCCESS)
+ {
+ return MBEDTLS_ERR_ECP_RANDOM_FAILED;
+ }
+ return 0;
+
+#else
+ return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+#endif
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_ecp_point_init(&p_pub->key);
+ mbedtls_mpi_init(&p_prv->key);
+ result = mbedtls_ecp_gen_keypair(&group,
+ &p_prv->key,
+ &p_pub->key,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ mbedtls_mpi_free(&p_prv->key);
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_ecp_point_init(&p_pub->key);
+ result = mbedtls_ecp_mul(&group,
+ &p_pub->key,
+ &p_prv->key,
+ &group.G,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&p_prv->key);
+ result = mbedtls_mpi_read_binary(&p_prv->key, p_raw_data, p_info->raw_private_key_size);
+
+ if (result == 0)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+ // Update bits in Curve25519 private key
+ if (p_prv->header.p_info->curve_type == NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE)
+ {
+ result = mbedtls_mpi_set_bit(&p_prv->key, 0, 0);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 1, 0);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 2, 0);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 254, 1);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 255, 0);
+ ASSERT(result == 0);
+ }
+#endif
+ if (mbedtls_ecp_check_privkey(&group, &p_prv->key) != 0)
+ {
+ result = MBEDTLS_ERR_ECP_INVALID_KEY;
+ }
+ }
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ mbedtls_mpi_free(&p_prv->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ int result;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ result = mbedtls_mpi_write_binary(&p_prv->key, p_raw_data, p_info->raw_private_key_size);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ mbedtls_ecp_point_init(&p_pub->key);
+
+ result = mbedtls_mpi_read_binary(&p_pub->key.X,
+ p_raw_data,
+ p_info->raw_private_key_size);
+ if (result != 0)
+ {
+ goto error_exit;
+ }
+
+ if (p_info->raw_public_key_size > p_info->raw_private_key_size)
+ {
+ result = mbedtls_mpi_read_binary(&p_pub->key.Y,
+ &p_raw_data[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ }
+
+ if (result != 0)
+ {
+ goto error_exit;
+ }
+
+ result = mbedtls_mpi_lset(&p_pub->key.Z, 1);
+
+ if (result == 0)
+ {
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ goto error_exit;
+ }
+ result = mbedtls_ecp_check_pubkey(&group, &p_pub->key);
+ mbedtls_ecp_group_free(&group);
+ }
+
+ if (result != 0)
+ {
+ goto error_exit;
+ }
+ return NRF_SUCCESS;
+
+error_exit:
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ int result;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t const * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ result = mbedtls_mpi_write_binary(&p_pub->key.X,
+ p_raw_data,
+ p_info->raw_private_key_size);
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ if (p_info->raw_public_key_size > p_info->raw_private_key_size)
+ {
+ result = mbedtls_mpi_write_binary(&p_pub->key.Y,
+ &p_raw_data[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ }
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_private_key_free(
+ void * p_private_key)
+{
+ nrf_crypto_backend_mbedtls_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t *)p_private_key;
+
+ mbedtls_mpi_free(&p_prv->key);
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_free(
+ void * p_public_key)
+{
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP192R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP224R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP256R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp384r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP384R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp521r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP521R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP192K1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP224K1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP256K1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_BP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_BP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_BP256R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_BP256R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp384r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_BP384R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_BP384R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_BP384R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_BP384R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp512r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_BP512R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_BP512R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_BP512R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_BP512R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_curve25519_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_CURVE25519,
+};
+#endif
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h
new file mode 100644
index 0000000..288c39c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h
@@ -0,0 +1,519 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_ECC_H__
+#define MBEDTLS_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+/*lint -restore*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Common structure holding private key for mbed TLS.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ mbedtls_mpi key; /**< @internal @brief mbed TLS specific key representation */
+} nrf_crypto_backend_mbedtls_ecc_private_key_t;
+
+
+/** @internal @brief Common structure holding public key for mbed TLS.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ mbedtls_ecp_point key; /**< @internal @brief mbed TLS specific key representation */
+} nrf_crypto_backend_mbedtls_ecc_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_free_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_private_key_free(
+ void * p_private_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_free_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_free(
+ void * p_public_key);
+
+
+/** @internal @brief Loads mbed TLS ECC group of specified curve type.
+ *
+ * @param[out] p_group Pointer to place where to load a group. Data have to be later deallocated.
+ * @param[in] curve_type ECC curve type from enum @ref nrf_crypto_ecc_curve_type_t.
+ * @returns true on success, false if curve is not supported or no found in mbed TLS.
+ */
+bool nrf_crypto_backend_mbedtls_ecc_group_load(
+ mbedtls_ecp_group * p_group,
+ struct nrf_crypto_ecc_curve_info_s const * p_info);
+
+
+/** @internal @brief Function that can be used as a parameter to mbed TLS functions requiring random
+ * number generator.
+ *
+ * It uses RNG from libary front end to generate random numbers.
+ *
+ * @param[in] p_param Opaque pointer passed by mbed TLS. Unused by this implementation.
+ * @param[out] p_data Pointer where to put random number.
+ * @returns 0 on success, mbed TLS error code on error.
+ */
+int nrf_crypto_backend_mbedtls_ecc_mbedtls_rng(void * p_param, unsigned char * p_data, size_t size);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192R1)
+#error "More than one backend enabled for secp192r1 (NIST 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp192r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp192r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp192r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp192r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp192r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp192r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp192r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp192r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp192r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp224r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp224r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp224r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp224r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp224r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp224r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp224r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp224r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp256r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp256r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp256r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp256r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp256r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP384R1)
+#error "More than one backend enabled for secp384r1 (NIST 384-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp384r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp384r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp384r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp384r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp384r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp384r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp384r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp384r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp384r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp384r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp384r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP521R1)
+#error "More than one backend enabled for secp521r1 (NIST 521-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp521r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp521r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp521r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp521r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp521r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp521r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp521r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp521r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp521r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp521r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp521r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp521r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192K1)
+#error "More than one backend enabled for secp192k1 (Koblitz 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192k1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp192k1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp192k1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp192k1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp192k1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp192k1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp192k1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp192k1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp192k1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp192k1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224K1)
+#error "More than one backend enabled for secp224k1 (Koblitz 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224k1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp224k1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp224k1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp224k1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp224k1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp224k1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp224k1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp224k1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp224k1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp224k1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256K1)
+#error "More than one backend enabled for secp256k1 (Koblitz 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256k1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp256k1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp256k1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp256k1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp256k1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp256k1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp256k1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp256k1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp256k1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp256k1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_BP256R1)
+#error "More than one backend enabled for bp256r1 (Brainpool 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_BP256R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp256r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_bp256r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_bp256r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_bp256r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_bp256r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_bp256r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_bp256r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_bp256r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_BP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_bp256r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_bp256r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_bp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_BP384R1)
+#error "More than one backend enabled for bp384r1 (Brainpool 384-bit).");
+#endif
+#define NRF_CRYPTO_ECC_BP384R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp384r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_bp384r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_bp384r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_bp384r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_bp384r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_bp384r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_bp384r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_bp384r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_BP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_bp384r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_bp384r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_bp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp384r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_BP512R1)
+#error "More than one backend enabled for bp512r1 (Brainpool 512-bit).");
+#endif
+#define NRF_CRYPTO_ECC_BP512R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp512r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_bp512r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_bp512r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_bp512r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_bp512r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_bp512r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_bp512r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_bp512r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_BP512R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP512R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_bp512r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_bp512r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_bp512r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp512r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_CURVE25519)
+#error "More than one backend enabled for Curve25519.");
+#endif
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_curve25519_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_curve25519_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_curve25519_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_curve25519_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_curve25519_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_curve25519_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_curve25519_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_curve25519_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_curve25519_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_curve25519_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_curve25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#endif // MBEDTLS_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c
new file mode 100644
index 0000000..02de8d7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <string.h>
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+#include "mbedtls/ecdh.h"
+/*lint -restore*/
+
+
+ret_code_t nrf_crypto_backend_mbedtls_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ int result;
+ mbedtls_mpi shared_secret_mpi;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t const * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&shared_secret_mpi);
+ result = mbedtls_ecdh_compute_shared(&group,
+ &shared_secret_mpi,
+ &p_pub->key,
+ &p_prv->key,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ if (result == 0)
+ {
+ result = mbedtls_mpi_write_binary(&shared_secret_mpi,
+ p_shared_secret,
+ p_info->raw_private_key_size);
+ }
+
+ mbedtls_mpi_free(&shared_secret_mpi);
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h
new file mode 100644
index 0000000..fac0e83
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_ECDH_H__
+#define MBEDTLS_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp384r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp384r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp521r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp521r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192k1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp192k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224k1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp224k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256k1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp256r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_bp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_BP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp384r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_bp384r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_BP384R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp512r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_bp512r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_BP512R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_curve25519_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_curve25519_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#endif // MBEDTLS_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c
new file mode 100644
index 0000000..04a5a90
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+#include "mbedtls/ecdsa.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+
+ret_code_t nrf_crypto_backend_mbedtls_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ int result;
+ mbedtls_mpi r_mpi;
+ mbedtls_mpi s_mpi;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&r_mpi);
+ mbedtls_mpi_init(&s_mpi);
+ result = mbedtls_ecdsa_sign(&group,
+ &r_mpi,
+ &s_mpi,
+ &p_prv->key,
+ p_data,
+ data_size,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result == 0)
+ {
+ result = mbedtls_mpi_write_binary(&r_mpi, p_signature, p_info->raw_private_key_size);
+ if (result == 0)
+ {
+ result = mbedtls_mpi_write_binary(&s_mpi,
+ &p_signature[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ }
+ }
+
+ mbedtls_mpi_free(&r_mpi);
+ mbedtls_mpi_free(&s_mpi);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+ mbedtls_mpi r_mpi;
+ mbedtls_mpi s_mpi;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t const * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&r_mpi);
+ mbedtls_mpi_init(&s_mpi);
+
+ result = mbedtls_mpi_read_binary(&r_mpi, p_signature, p_info->raw_private_key_size);
+ if (result == 0)
+ {
+ result = mbedtls_mpi_read_binary(&s_mpi,
+ &p_signature[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ if (result == 0)
+ {
+ result = mbedtls_ecdsa_verify(&group, p_data, data_size, &p_pub->key, &r_mpi, &s_mpi);
+ }
+ }
+
+ mbedtls_ecp_group_free(&group);
+ mbedtls_mpi_free(&r_mpi);
+ mbedtls_mpi_free(&s_mpi);
+
+ if (result == MBEDTLS_ERR_ECP_VERIFY_FAILED)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+ else if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h
new file mode 100644
index 0000000..7ad85a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h
@@ -0,0 +1,240 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_ECDSA_H__
+#define MBEDTLS_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp192r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp192r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp224r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp224r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp256r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp256r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp384r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp384r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp384r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp384r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp521r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp521r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp521r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp521r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp192k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp192k1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp192k1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp192k1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp224k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp224k1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp224k1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp224k1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp256k1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp256k1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_bp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_bp256r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_bp256r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_bp256r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_bp384r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_bp384r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_bp384r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_bp384r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_bp512r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_bp512r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_bp512r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_bp512r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_curve25519_sign_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_verify_context_t;
+// No ECDSA implementation for Curve25519
+#define nrf_crypto_backend_curve25519_sign NULL
+#define nrf_crypto_backend_curve25519_verify NULL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#endif // MBEDTLS_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c
new file mode 100644
index 0000000..b244e0a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "mbedtls_backend_hash.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/md.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256)
+
+static ret_code_t mbedtls_backend_hash_sha256_init(void * const p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha256_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ mbedtls_sha256_init(p_backend_context);
+
+ mbedtls_sha256_starts(p_backend_context, 0);
+
+ return NRF_SUCCESS;
+}
+
+static uint32_t mbedtls_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha256_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ mbedtls_sha256_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t mbedtls_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha256_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ mbedtls_sha256_finish(p_backend_context, p_digest);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = mbedtls_backend_hash_sha256_init,
+ .update_fn = mbedtls_backend_hash_sha256_update,
+ .finalize_fn = mbedtls_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+
+static ret_code_t mbedtls_backend_hash_sha512_init(void * p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha512_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ mbedtls_sha512_init(p_backend_context);
+
+ mbedtls_sha512_starts(p_backend_context, 0);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hash_sha512_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha512_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ mbedtls_sha512_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hash_sha512_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha512_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ mbedtls_sha512_finish(p_backend_context, p_digest);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA512;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info =
+{
+ .init_fn = mbedtls_backend_hash_sha512_init,
+ .update_fn = mbedtls_backend_hash_sha512_update,
+ .finalize_fn = mbedtls_backend_hash_sha512_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha512_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA512
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h
new file mode 100644
index 0000000..f69be9b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_HASH_H__
+#define MBEDTLS_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_hash nrf_crypto mbedtls backend hash
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief Hash functionality provided by the nrf_crypto mbedtls backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+
+/*lint -save -e????*/
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-256
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+
+// Flag that SHA-256 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**brief nrf_crypto_hash context for SHA-256 in nrf_crypto mbedtls backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ mbedtls_sha256_context context; /**< Hash context internal to mbedtls. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-512
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+#error "Duplicate definition of SHA-512. More than one backend enabled");
+#endif
+
+// Flag that SHA-512 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA512_ENABLED 1
+
+
+/**brief nrf_crypto_hash context for SHA-512 in nrf_crypto mbedtls backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ mbedtls_sha512_context context; /**< Hash context internal to mbedtls. */
+} nrf_crypto_backend_hash_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/**@} */
+
+#endif //MBEDTLS_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c
new file mode 100644
index 0000000..0a6658c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c
@@ -0,0 +1,230 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "nrf_log.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "mbedtls_backend_hmac.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+static ret_code_t mbedtls_backend_hmac_init_sha256(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha256_context_t *)p_context;
+
+ // Memset context to 0. This is equevalend with a call to mbedtls_md_init().
+ memset(p_ctx->md_ctx_buffer, 0, sizeof(p_ctx->md_ctx_buffer));
+ memset(p_ctx->hmac_ctx_buffer, 0, sizeof(p_ctx->hmac_ctx_buffer));
+
+ // Set info and context pointers to buffer allocated by user.
+ // This is Normally handled by mbedtls_md_setup(), but has to be done here in order
+ // to avoid dynamic allocation of memory inside mbed TLS.
+ p_ctx->mbedtls_ctx.md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+ p_ctx->mbedtls_ctx.md_ctx = p_ctx->md_ctx_buffer;
+ p_ctx->mbedtls_ctx.hmac_ctx = p_ctx->hmac_ctx_buffer;
+
+ // Enter key to start
+ err_code = mbedtls_md_hmac_starts(&p_ctx->mbedtls_ctx,
+ p_key,
+ key_size);
+
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_starts: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_update_sha256(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha256_context_t *)p_context;
+
+ err_code = mbedtls_md_hmac_update(&p_ctx->mbedtls_ctx, p_data, size);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_update: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_finalize_sha256(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha256_context_t * const p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha256_context_t *)p_context;
+
+ // Set the digest length to 0 so that this is used in case of any error.
+ *p_size = 0;
+
+ err_code = mbedtls_md_hmac_finish(&p_ctx->mbedtls_ctx, p_digest);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_finish: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA256 using mbed TLS backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info =
+{
+ .init_fn = mbedtls_backend_hmac_init_sha256,
+ .update_fn = mbedtls_backend_hmac_update_sha256,
+ .finalize_fn = mbedtls_backend_hmac_finalize_sha256,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha256_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA256_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+
+static ret_code_t mbedtls_backend_hmac_init_sha512(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha512_context_t *)p_context;
+
+ // Memset context to 0. This is equevalend with a call to mbedtls_md_init().
+ memset(p_ctx->md_ctx_buffer, 0, sizeof(p_ctx->md_ctx_buffer));
+ memset(p_ctx->hmac_ctx_buffer, 0, sizeof(p_ctx->hmac_ctx_buffer));
+
+ // Set info and context pointers to buffer allocated by user.
+ // (Normally handled by mbedtls_md_setup())
+ p_ctx->mbedtls_ctx.md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
+ p_ctx->mbedtls_ctx.md_ctx = p_ctx->md_ctx_buffer;
+ p_ctx->mbedtls_ctx.hmac_ctx = p_ctx->hmac_ctx_buffer;
+
+ // Enter key to start
+ err_code = mbedtls_md_hmac_starts(&p_ctx->mbedtls_ctx, p_key, key_size);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_starts: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_update_sha512(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha512_context_t *)p_context;
+
+ err_code = mbedtls_md_hmac_update(&p_ctx->mbedtls_ctx, p_data, size);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_update: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_finalize_sha512(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha512_context_t *)p_context;
+
+ // Set the digest length to 0 so that this is used in case of any error.
+ *p_size = 0;
+
+ err_code = mbedtls_md_hmac_finish(&p_ctx->mbedtls_ctx, p_digest);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_finish: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL; }
+
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA512 using mbed TLS backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info =
+{
+ .init_fn = mbedtls_backend_hmac_init_sha512,
+ .update_fn = mbedtls_backend_hmac_update_sha512,
+ .finalize_fn = mbedtls_backend_hmac_finalize_sha512,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha512_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA512_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h
new file mode 100644
index 0000000..2645bba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_HMAC_H__
+#define MBEDTLS_BACKEND_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_hmac mbed TLS backend for HMAC
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief Backend wrapper for mbed TLS. None of these types should be used directly by the
+ * application.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS) && \
+ ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512) )
+
+#include "nrf_crypto_hmac_shared.h"
+/*lint -save -e????*/
+#include "mbedtls/md.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NRF_CRYPTO_HMAC_ENABLED
+#define NRF_CRYPTO_HMAC_ENABLED 1
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA256)
+#error "Duplicate definition of HMAC SHA-256. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_HMAC_SHA256_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the mbed TLS backend wrapper for HMAC SHA256.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha256_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context.
+ mbedtls_md_context_t mbedtls_ctx; //!< Mbed TLS context object.
+ uint8_t md_ctx_buffer[sizeof(mbedtls_sha256_context)]; //!< Message digest buffer for mbed TLS.
+ uint16_t hmac_ctx_buffer[64]; //!< Hash buffer for mbed TLS of size defined in mbedtls_sha256_info in md_internal.h.
+} nrf_crypto_backend_mbedtls_hmac_sha256_context_t;
+
+/**
+ * @internal @brief Context for HMAC SHA256 using mbed TLS backend.
+ */
+typedef nrf_crypto_backend_mbedtls_hmac_sha256_context_t nrf_crypto_backend_hmac_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA512)
+#error "Duplicate definition of HMAC SHA-512. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_HMAC_SHA512_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the mbed TLS backend wrapper for HMAC SHA512.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha512_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context header.
+ mbedtls_md_context_t mbedtls_ctx; //!< Mbed TLS context object.
+ uint8_t md_ctx_buffer[sizeof(mbedtls_sha512_context)]; //!< Message digest buffer for mbed TLS.
+ uint16_t hmac_ctx_buffer[128]; //!< Hash buffer for mbed TLS of size defined in mbedtls_sha512_info in md_internal.h.
+} nrf_crypto_backend_mbedtls_hmac_sha512_context_t;
+
+/**
+ * @internal @brief Context for HMAC SHA512 using mbed TLS backend.
+ */
+typedef nrf_crypto_backend_mbedtls_hmac_sha512_context_t nrf_crypto_backend_hmac_sha512_context_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS) && ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512) )
+
+/**@} */
+
+#endif // MBEDTLS_BACKEND_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c
new file mode 100644
index 0000000..aa37d67
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <string.h>
+#include <stdint.h>
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_mem.h"
+/*lint -save -e????*/
+#include "mbedtls/platform.h"
+/*lint -restore*/
+
+
+#if NRF_CRYPTO_ALLOC_ON_STACK
+#error "MBED TLS backend does not support memory allocation on stack. Use different allocator."
+#endif
+
+
+/** @internal @brief Function to use NRF_CRYPTO_ALLOC for MBED TLS memory allocation.
+ */
+static void * mbedtls_backend_calloc(size_t count, size_t size)
+{
+ size_t total_size = count * size;
+ void * p_data = NRF_CRYPTO_ALLOC(total_size);
+ if (p_data != NULL)
+ {
+ memset(p_data, 0, total_size);
+ }
+ return p_data;
+}
+
+
+/** @internal @brief Function to use NRF_CRYPTO_FREE for MBED TLS memory deallocation.
+ */
+static void mbedtls_backend_free(void * p_data)
+{
+ NRF_CRYPTO_FREE(p_data);
+}
+
+
+/** @internal @brief Function to initialize MBED TLS backend - setup memory management for.
+ */
+static ret_code_t mbedtls_backend_init(void)
+{
+ (void)mbedtls_platform_set_calloc_free(mbedtls_backend_calloc, mbedtls_backend_free);
+ return NRF_SUCCESS;
+}
+
+
+/** @internal @brief Function to uninitialize MBED TLS backend - currently no implementation is required.
+ */
+static ret_code_t mbedtls_backend_uninit(void)
+{
+ // Empty implementation
+ return NRF_SUCCESS;
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const mbedtls_backend) =
+{
+ .init_fn = mbedtls_backend_init,
+ .uninit_fn = mbedtls_backend_uninit,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c
new file mode 100644
index 0000000..534d756
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <stdbool.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "app_util.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_shared.h"
+#include "micro_ecc_backend_ecc.h"
+#include "micro_ecc_backend_shared.h"
+#include "uECC.h"
+
+
+typedef uECC_Curve (*micro_ecc_curve_fn_t)(void);
+
+
+int nrf_crypto_backend_micro_ecc_rng_callback(uint8_t * dest, unsigned size)
+{
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+ ret_code_t result;
+
+ result = nrf_crypto_rng_vector_generate(dest, size);
+
+ // Return values compatible with mbed TLS
+ if (result != NRF_SUCCESS)
+ {
+ return 0;
+ }
+ return 1;
+
+#else
+ UNUSED_PARAMETER(dest);
+ UNUSED_PARAMETER(size);
+ return 0;
+#endif
+}
+
+
+uECC_Curve nrf_crypto_backend_micro_ecc_curve_get(
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_key)
+{
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_key;
+
+ //lint -save -e611 (Suspicious cast)
+ micro_ecc_curve_fn_t micro_ecc_curve_fn =
+ (micro_ecc_curve_fn_t)p_key_header->p_info->p_backend_data;
+ //lint -restore
+
+ uECC_Curve p_micro_ecc_curve = micro_ecc_curve_fn();
+
+ return p_micro_ecc_curve;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_private_key;
+ nrf_crypto_backend_micro_ecc_common_key_t * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_public_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+ uECC_set_rng(nrf_crypto_backend_micro_ecc_rng_callback);
+
+ result = uECC_make_key((uint8_t *)(&p_pub->key[0]),
+ (uint8_t *)(&p_prv->key[0]),
+ p_micro_ecc_curve);
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+ nrf_crypto_backend_micro_ecc_common_key_t * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_public_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+ result = uECC_compute_public_key((uint8_t *)(&p_prv->key[0]),
+ (uint8_t *)(&p_pub->key[0]),
+ p_micro_ecc_curve);
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_swap_endian((uint8_t *)(&p_prv->key[0]),
+ p_raw_data,
+ p_info->raw_private_key_size);
+#else
+ memcpy(&p_prv->key[0], p_raw_data, p_info->raw_private_key_size);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_swap_endian(p_raw_data,
+ (uint8_t *)(&p_prv->key[0]),
+ p_info->raw_private_key_size);
+#else
+ memcpy(p_raw_data, &p_prv->key[0], p_info->raw_private_key_size);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_pub);
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_double_swap_endian((uint8_t *)(&p_pub->key[0]),
+ p_raw_data,
+ p_info->raw_private_key_size);
+#else
+ memcpy(&p_pub->key[0], p_raw_data, p_info->raw_public_key_size);
+#endif
+
+#if !NRF_CRYPTO_BACKEND_MICRO_ECC_PUBLIC_KEY_TRUSTED_ENABLED
+ if (!uECC_valid_public_key((uint8_t *)(&p_pub->key[0]), p_micro_ecc_curve))
+ {
+ return NRF_ERROR_CRYPTO_ECC_INVALID_KEY;
+ }
+#else
+ UNUSED_PARAMETER(p_micro_ecc_curve);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_double_swap_endian(p_raw_data,
+ (uint8_t *)(&p_pub->key[0]),
+ p_info->raw_private_key_size);
+#else
+ memcpy(p_raw_data, &p_pub->key[0], p_info->raw_public_key_size);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+// Make sure that common key structure match secp192r1 (NIST 192-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp192r1_private_key_t, key),
+ "Common uECC private key structure does not match secp192r1 (NIST 192-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp192r1_public_key_t, key),
+ "Common ECC public key structure does not match secp192r1 (NIST 192-bit) one.");
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp192r1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp192r1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp192r1,
+ //lint -restore
+};
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+// Make sure that common key structure match secp224r1 (NIST 224-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp224r1_private_key_t, key),
+ "Common uECC private key structure does not match secp224r1 (NIST 224-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp224r1_public_key_t, key),
+ "Common ECC public key structure does not match secp224r1 (NIST 224-bit) one.");
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp224r1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp224r1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp224r1,
+ //lint -restore
+};
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+// Make sure that common key structure match secp256r1 (NIST 256-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_private_key_t, key),
+ "Common uECC private key structure does not match secp256r1 (NIST 256-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_public_key_t, key),
+ "Common ECC public key structure does not match secp256r1 (NIST 256-bit) one.");
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256r1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp256r1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp256r1,
+ //lint -restore
+};
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+// Make sure that common key structure match secp256k1 (Koblitz 256-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256k1_private_key_t, key),
+ "Common uECC private key structure does not match secp256k1 (Koblitz 256-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256k1_public_key_t, key),
+ "Common ECC public key structure does not match secp256k1 (Koblitz 256-bit) one.");
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256k1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp256k1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp256k1,
+ //lint -restore
+};
+
+#endif
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h
new file mode 100644
index 0000000..cafa506
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h
@@ -0,0 +1,303 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MICRO_ECC_BACKEND_ECC_H__
+#define MICRO_ECC_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+#include "uECC.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Represents common uECC backend key structure.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[1]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_micro_ecc_common_key_t;
+
+
+/** @internal @brief Callback RNG function that can be provided to uECC API.
+ * @param dest Destination buffer.
+ * @param size Size of the buffer.
+ * @return 1 on success, 0 on error.
+ */
+int nrf_crypto_backend_micro_ecc_rng_callback(uint8_t * dest, unsigned size);
+
+
+/** @internal @brief Gets uECC type based on provided key.
+ * @param p_key uECC backend key (public or private).
+ * @return uECC specific value representing a curve.
+ */
+uECC_Curve nrf_crypto_backend_micro_ecc_curve_get(
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_key);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192R1)
+#error "More than one backend enabled for secp192r1 (NIST 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp192r1 (NIST 192-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[192 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp192r1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp192r1 (NIST 192-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 192 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp192r1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp192r1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp192r1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp192r1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp192r1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp192r1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp192r1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp192r1_private_key_free NULL
+#define nrf_crypto_backend_secp192r1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp224r1 (NIST 224-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[224 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp224r1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp224r1 (NIST 224-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 224 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp224r1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp224r1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp224r1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp224r1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp224r1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp224r1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp224r1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp224r1_private_key_free NULL
+#define nrf_crypto_backend_secp224r1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp256r1 (NIST 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256r1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp256r1 (NIST 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256r1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp256r1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp256r1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp256r1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256K1)
+#error "More than one backend enabled for secp256k1 (Koblitz 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp256k1 (Koblitz 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256k1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp256k1 (Koblitz 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256k1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp256k1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp256k1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp256k1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp256k1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp256k1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp256k1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp256k1_private_key_free NULL
+#define nrf_crypto_backend_secp256k1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c
new file mode 100644
index 0000000..a63307e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <string.h>
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_shared.h"
+#include "micro_ecc_backend_ecc.h"
+#include "micro_ecc_backend_shared.h"
+#include "uECC.h"
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+ result = uECC_shared_secret((uint8_t const *)(&p_pub->key[0]),
+ (uint8_t const *)(&p_prv->key[0]),
+ p_shared_secret,
+ p_micro_ecc_curve);
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_swap_endian_in_place(p_shared_secret, p_info->raw_private_key_size);
+#else
+ UNUSED_PARAMETER(p_info);
+#endif
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h
new file mode 100644
index 0000000..cdf366b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MICRO_ECC_BACKEND_ECDH_H__
+#define MICRO_ECC_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp192r1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp224r1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp256r1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp256k1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c
new file mode 100644
index 0000000..f72e6dc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_mem.h"
+#include "micro_ecc_backend_ecc.h"
+#include "micro_ecc_backend_shared.h"
+#include "uECC.h"
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+#if ECC_BACKEND_SWAP_BYTES
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ size_t hash_size = MIN(data_size, p_info->raw_private_key_size);
+ uint8_t hash_le[NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE];
+
+ nrf_crypto_internal_swap_endian(hash_le, p_data, hash_size);
+
+ uECC_set_rng(nrf_crypto_backend_micro_ecc_rng_callback);
+
+ result = uECC_sign((uint8_t const *)(&p_prv->key[0]),
+ hash_le,
+ hash_size,
+ p_signature,
+ p_micro_ecc_curve);
+
+ nrf_crypto_internal_double_swap_endian_in_place(p_signature, p_info->raw_private_key_size);
+
+#else
+
+ uECC_set_rng(nrf_crypto_backend_micro_ecc_rng_callback);
+
+ result = uECC_sign((uint8_t const *)(&p_prv->key[0]),
+ p_data,
+ data_size,
+ p_signature,
+ p_micro_ecc_curve);
+
+#endif
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_public_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_pub);
+
+#if ECC_BACKEND_SWAP_BYTES
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ size_t hash_size = MIN(data_size, p_info->raw_private_key_size);
+ uint8_t hash_le [NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE];
+ uint8_t signature_le[NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE];
+
+ nrf_crypto_internal_swap_endian(hash_le, p_data, hash_size);
+
+ nrf_crypto_internal_double_swap_endian(signature_le,
+ p_signature,
+ p_info->raw_private_key_size);
+
+ result = uECC_verify((uint8_t const *)(&p_pub->key[0]),
+ hash_le,
+ hash_size,
+ signature_le,
+ p_micro_ecc_curve);
+
+#else
+
+ result = uECC_verify((uint8_t const *)(&p_pub->key[0]),
+ p_data,
+ data_size,
+ p_signature,
+ p_micro_ecc_curve);
+
+#endif
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h
new file mode 100644
index 0000000..a52d193
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MICRO_ECC_BACKEND_ECDSA_H__
+#define MICRO_ECC_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_verify_context_t;
+#define nrf_crypto_backend_secp192r1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp192r1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_verify_context_t;
+#define nrf_crypto_backend_secp224r1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp224r1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_verify_context_t;
+#define nrf_crypto_backend_secp256r1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp256r1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_verify_context_t;
+#define nrf_crypto_backend_secp256k1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp256k1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h
new file mode 100644
index 0000000..019f280
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef MICRO_ECC_BACKEND_SHARED_H__
+#define MICRO_ECC_BACKEND_SHARED_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include "uECC.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_LITTLE_ENDIAN)
+#define ECC_BACKEND_SWAP_BYTES (!uECC_VLI_NATIVE_LITTLE_ENDIAN)
+#else
+#define ECC_BACKEND_SWAP_BYTES uECC_VLI_NATIVE_LITTLE_ENDIAN
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c
new file mode 100644
index 0000000..d202f35
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG)
+
+#include "nrf.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_rng.h"
+
+
+static ret_code_t nrf_hw_backend_init(void)
+{
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ uint32_t ret_val;
+ ret_val = nrf_crypto_rng_init(NULL, NULL);
+ return ret_val;
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ return NRF_SUCCESS;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED
+}
+
+
+static ret_code_t nrf_hw_backend_uninit(void)
+{
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ uint32_t ret_val;
+ ret_val = nrf_crypto_rng_uninit();
+ return ret_val;
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ return NRF_SUCCESS;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_AUTO_INIT)
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const nrf_hw_backend) =
+{
+ .init_fn = nrf_hw_backend_init,
+ .uninit_fn = nrf_hw_backend_uninit
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c
new file mode 100644
index 0000000..e8331e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#include "nrf_crypto_rng.h"
+#include "nrf_drv_rng.h"
+
+
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context,
+ void * const p_temp_buffer)
+{
+ ret_code_t ret_val;
+
+ UNUSED_PARAMETER(p_context);
+ UNUSED_PARAMETER(p_temp_buffer);
+
+ ret_val = nrf_drv_rng_init(NULL);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ nrf_drv_rng_uninit();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex)
+{
+ UNUSED_PARAMETER(use_mutex);
+ UNUSED_PARAMETER(p_context);
+
+ nrf_drv_rng_block_rand(p_target, size);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ UNUSED_PARAMETER(p_context);
+ UNUSED_PARAMETER(p_temp_buffer);
+ UNUSED_PARAMETER(p_input_data);
+ UNUSED_PARAMETER(size);
+
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h
new file mode 100644
index 0000000..fcf6b8d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_HW_BACKEND_RNG_H__
+#define NRF_HW_BACKEND_RNG_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_nrf_hw_backend_rng nrf_crypto HW RNG backend
+ * @{
+ * @ingroup nrf_crypto_backends
+ *
+ * @brief RNG functionality provided by the nrf_crypto nRF HW RNG backend.
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#if !NRF_MODULE_ENABLED(RNG)
+#error Enable RNG_ENABLED in sdk_config.h.
+#endif
+
+#if !NRFX_RNG_CONFIG_ERROR_CORRECTION
+#error Enable NRFX_RNG_CONFIG_ERROR_CORRECTION and RNG_CONFIG_ERROR_CORRECTION in sdk_config.h.
+#endif
+
+#include "nrf_crypto_rng_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#error "More than one RNG backend enabled."
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#define NRF_CRYPTO_RNG_ENABLED 1
+
+
+/**
+ * @internal @brief Context for nRF RNG peripheral.
+ */
+typedef struct
+{
+ nrf_crypto_rng_internal_context_t header; //!< Internal common context header.
+} nrf_crypto_backend_rng_context_t;
+
+/**
+ * @internal @brief Dummy temp buffer for nRF RNG peripheral.
+ */
+typedef struct
+{
+ uint32_t reserved;
+} nrf_crypto_backend_rng_temp_buffer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+/**@} */
+
+#endif // NRF_HW_BACKEND_RNG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c
new file mode 100644
index 0000000..649904b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#include "nrf_crypto_rng.h"
+#include "nrf_drv_rng.h"
+#include "nrf_hw_backend_rng_mbedtls.h"
+
+
+// Function to convert mbedtls error codes to ret_code_t.
+static ret_code_t result_get(int mbedtls_ret_val)
+{
+ ret_code_t ret_val;
+ switch (mbedtls_ret_val)
+ {
+ case 0:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+
+// Callback function used by mbed TLS to seed and reseed.
+static int entropy_callback(void * p_entropy, unsigned char * p_buffer, size_t size)
+{
+ UNUSED_PARAMETER(p_entropy);
+
+ nrf_drv_rng_block_rand(p_buffer, size);
+
+ return 0;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context, void * const p_temp_buffer)
+{
+ ret_code_t ret_val;
+ int mbedtls_ret_val;
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ UNUSED_PARAMETER(p_temp_buffer);
+
+ ret_val = nrf_drv_rng_init(NULL);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ mbedtls_ctr_drbg_init(p_mbedtls_context);
+
+ // Initial seeding. The nrf_crypto_rng API does not support additional entropy in the initial
+ // seeding. Additional entropy can be provided using nrf_crypto_rng_backend_reseed(),
+ // which calls mbedtls_ctr_drbg_reseed().
+ mbedtls_ret_val = mbedtls_ctr_drbg_seed(p_mbedtls_context,
+ entropy_callback,
+ NULL,
+ NULL,
+ 0);
+
+ ret_val = result_get(mbedtls_ret_val);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context)
+{
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ mbedtls_ctr_drbg_free(p_mbedtls_context);
+ nrf_drv_rng_uninit();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex)
+{
+ int mbedtls_ret_val;
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ UNUSED_PARAMETER(use_mutex);
+
+ mbedtls_ret_val = mbedtls_ctr_drbg_random(p_mbedtls_context, p_target, size);
+
+ return result_get(mbedtls_ret_val);
+}
+
+
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ int mbedtls_ret_val;
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ UNUSED_PARAMETER(p_temp_buffer);
+
+ mbedtls_ret_val = mbedtls_ctr_drbg_reseed(p_mbedtls_context, p_input_data, size);
+
+ return result_get(mbedtls_ret_val);
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h
new file mode 100644
index 0000000..53daba0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_HW_BACKEND_RNG_MBEDTLS_H__
+#define NRF_HW_BACKEND_RNG_MBEDTLS_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_nrf_hw_backend_rng_mbedtls nrf_crypto HW RNG backend using mbedtls CTR-DRBG
+ * @{
+ * @ingroup nrf_crypto_nrf_hw_backend_rng
+ *
+ * @brief RNG functionality provided by the nrf_crypto nRF HW RNG backend and mbedtls CTR-DRBG.
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#if !NRF_MODULE_ENABLED(RNG)
+#error Enable RNG_ENABLED in sdk_config.h.
+#endif
+
+#if !NRFX_RNG_CONFIG_ERROR_CORRECTION
+#error Enable NRFX_RNG_CONFIG_ERROR_CORRECTION and RNG_CONFIG_ERROR_CORRECTION in sdk_config.h.
+#endif
+
+/*lint -save -e????*/
+#include "mbedtls/ctr_drbg.h"
+/*lint -restore*/
+#include "nrf_crypto_rng_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#error "More than one RNG backend enabled."
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#define NRF_CRYPTO_RNG_ENABLED 1
+
+
+/**
+ * @internal @brief Context for nRF RNG peripheral with mbed tls CTR-DRBG.
+ */
+typedef struct
+{
+ nrf_crypto_rng_internal_context_t header; //!< Internal common context header.
+ mbedtls_ctr_drbg_context mbedtls_context; //!< mbed TLS CTR-DRBG context.
+} nrf_crypto_backend_rng_context_t;
+
+/**
+ * @internal @brief Dummy temp buffer for nRF RNG peripheral with mbed tls CTR-DRBG.
+ */
+typedef struct
+{
+ uint32_t reserved;
+} nrf_crypto_backend_rng_temp_buffer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+/**@} */
+
+#endif // NRF_HW_BACKEND_RNG_MBEDTLS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c
new file mode 100644
index 0000000..1360662
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
+
+#include "nrf_sw_backend_hash.h"
+#include "sha256.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+
+#if defined(NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && \
+ (NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 1)
+
+ #define LITTLE_ENDIAN_HASH (true)
+
+#elif defined(NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && \
+ (NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 0)
+
+ #define LITTLE_ENDIAN_HASH (false)
+
+#else
+
+ #define LITTLE_ENDIAN_HASH (false)
+
+ #warning NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+
+static ret_code_t nrf_sw_backend_hash_sha256_init(void * const p_context)
+{
+ ret_code_t ret_val;
+
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ sha256_context_t * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *) p_context)->context);
+
+ ret_val = sha256_init(p_backend_context);
+
+ return ret_val;
+}
+
+static uint32_t nrf_sw_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t len)
+{
+ ret_code_t ret_val;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ sha256_context_t * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * ) p_context)->context);
+
+ ret_val = sha256_update(p_backend_context, p_data, len);
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_sw_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_len)
+{
+ ret_code_t ret_val;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ sha256_context_t * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * )p_context)->context);
+
+ if (NRF_CRYPTO_HASH_SIZE_SHA256 > *p_digest_len)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+
+ ret_val = sha256_final(p_backend_context, p_digest, LITTLE_ENDIAN_HASH);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ *p_digest_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ return NRF_SUCCESS;
+
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = nrf_sw_backend_hash_sha256_init,
+ .update_fn = nrf_sw_backend_hash_sha256_update,
+ .finalize_fn = nrf_sw_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h
new file mode 100644
index 0000000..b5c025c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_SW_BACKEND_HASH_H__
+#define NRF_SW_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_nrf_sw_backend_hash nrf_crypto nRF SW backend hash
+ * @{
+ * @ingroup nrf_crypto_nrf_sw_backend
+ *
+ * @brief Legacy hash functionality for bootloader use in nRFx devices
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
+
+#include "sha256.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_hash_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-256
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+
+// Flag that SHA-256 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256)
+
+
+/**@brief nrf_crypto_hash context for SHA-256 in nrf_crypto nrf_sw backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ sha256_context_t context; /**< Hash context internal to nrf_sw. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
+
+/**@} */
+
+#endif // NRF_SW_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c
new file mode 100644
index 0000000..14588d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "oberon_backend_chacha_poly_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_OBERON_CHACHA_POLY_AEAD)
+
+static ret_code_t backend_cc310_init(void * const p_context, uint8_t * p_key)
+{
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+
+ if (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256)
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ memcpy(p_ctx->key, p_key, sizeof(p_ctx->key));
+
+ return NRF_SUCCESS;
+}
+
+static inline ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cc310_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+
+{
+ int result;
+
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+ if ((adata_size == 0) || (data_in_size == 0))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ if (mac_size != NRF_CRYPTO_CHACHA_POLY_MAC_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if (nonce_size != NRF_CRYPTO_CHACHA_POLY_NONCE_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ occ_chacha20_poly1305_encrypt_aad(p_mac,
+ p_data_out,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_ctx->key);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = occ_chacha20_poly1305_decrypt_aad(p_mac,
+ p_data_out,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_ctx->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ }
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+nrf_crypto_aead_info_t const g_nrf_crypto_chacha_poly_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_CHACHA_POLY,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_CHACHA_POLY_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h
new file mode 100644
index 0000000..990db3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef OBERON_BACKEND_CHACHA_POLY_AEAD_H__
+#define OBERON_BACKEND_CHACHA_POLY_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_oberon_backend_chacha_poly_aead nrf_crypto Oberon backend CHACHA_POLY AEAD
+ * @{
+ * @ingroup nrf_crypto_oberon_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto Oberon backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "nrf_crypto_aead_shared.h"
+#include "occ_chacha20_poly1305.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_OBERON_CHACHA_POLY_BACKEND_KEY_SIZE (32)
+
+/* CHACHA-POLY */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CHACHA_POLY)
+#error "Duplicate definition of CHACHA-POLY mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_CHACHA_POLY_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aead frontend can be compiled
+#undef NRF_CRYPTO_OBERON_CHACHA_POLY_AEAD_ENABLED
+#define NRF_CRYPTO_OBERON_CHACHA_POLY_AEAD_ENABLED 1 // aead backend for Oberon can be compiled
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CHACHA_POLY_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+
+ uint8_t key[NRF_CRYPTO_OBERON_CHACHA_POLY_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_chacha_poly_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+/** @} */
+
+#endif // OBERON_BACKEND_CHACHA_POLY_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c
new file mode 100644
index 0000000..ed8f510
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c
@@ -0,0 +1,458 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdbool.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "app_util.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_shared.h"
+#include "oberon_backend_ecc.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+#include "occ_ecdh_p256.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+#include "occ_curve25519.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+#include "occ_ed25519.h"
+#endif
+
+
+/** @internal @brief Structure holding private key common to all curves implemented by the Oberon.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_oberon_private_key_t;
+
+
+/** @internal @brief Structure holding public key common to all curves implemented by the Oberon.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[64]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_oberon_public_key_t;
+
+
+/** @internal @brief Function to hold copy function (can be simple mem copy or copy with endian swap).
+ */
+typedef void (*copy_fn_t)(void * p_dest, void const * p_src, size_t size);
+
+
+ret_code_t nrf_crypto_backend_oberon_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_oberon_private_key_t const * p_prv =
+ (nrf_crypto_backend_oberon_private_key_t const *)p_private_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_prv->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_raw_data, p_prv->key, p_prv->header.p_info->raw_private_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_oberon_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_oberon_public_key_t * p_pub =
+ (nrf_crypto_backend_oberon_public_key_t *)p_public_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_pub->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_pub->key, p_raw_data, p_pub->header.p_info->raw_public_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_oberon_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_oberon_public_key_t const * p_pub =
+ (nrf_crypto_backend_oberon_public_key_t const *)p_public_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_pub->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_raw_data, p_pub->key, p_pub->header.p_info->raw_public_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1) \
+ || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+ret_code_t nrf_crypto_backend_oberon_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_oberon_private_key_t * p_prv =
+ (nrf_crypto_backend_oberon_private_key_t *)p_private_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_prv->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_prv->key, p_raw_data, p_prv->header.p_info->raw_private_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519) \
+ || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+static ret_code_t oberon_vector_generate(uint8_t * p_data, size_t size)
+{
+#if defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 1)
+
+ return nrf_crypto_rng_vector_generate(p_data, size);
+
+#elif defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 0)
+
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+}
+
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+// Make sure that common key structure match secp256r1 key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_private_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_private_key_t, key),
+ "Common Oberon private key structure does not match secp256r1 one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_public_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_public_key_t, key),
+ "Common Oberon public key structure does not match secp256r1 one.");
+
+
+ret_code_t nrf_crypto_backend_oberon_ecc_secp256r1_rng(uint8_t data[32])
+{
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+ static const uint8_t min_value[32] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ static const uint8_t max_value[32] =
+ {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x50,
+ };
+ return nrf_crypto_rng_vector_generate_in_range(data, min_value, max_value, 32);
+
+#else
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+#endif
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_private_key_t * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ result = nrf_crypto_backend_oberon_ecc_secp256r1_rng(p_prv->key);
+
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ result = occ_ecdh_p256_public_key(p_pub->key, p_prv->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_private_key_t const * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ result = occ_ecdh_p256_public_key(p_pub->key, p_prv->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256r1_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp256r1_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&memcpy,
+ //lint -restore
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+// Make sure that common key structure match Curve25519 key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_private_key_t, key) ==
+ offsetof(nrf_crypto_backend_curve25519_private_key_t, key),
+ "Common Oberon private key structure does not match Curve25519 one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_public_key_t, key) ==
+ offsetof(nrf_crypto_backend_curve25519_public_key_t, key),
+ "Common Oberon public key structure does not match Curve25519 one.");
+
+
+ret_code_t nrf_crypto_backend_curve25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ ret_code_t result;
+
+ nrf_crypto_backend_curve25519_private_key_t * p_prv =
+ (nrf_crypto_backend_curve25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_curve25519_public_key_t * p_pub =
+ (nrf_crypto_backend_curve25519_public_key_t *)p_public_key;
+
+ result = oberon_vector_generate(p_prv->key, sizeof(p_prv->key));
+
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ p_prv->key[0] &= 0xF8; // Private key is multiply of 8 (by definition), so lower 3 bits are 0.
+ p_prv->key[31] &= 0x7F; // Highest bit has to be 0, because private key is 255-bit long.
+ p_prv->key[31] |= 0x40; // Bit 254 has to be 1 (by definition)
+
+ occ_curve25519_scalarmult_base(p_pub->key, p_prv->key);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_curve25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ nrf_crypto_backend_curve25519_private_key_t * p_prv =
+ (nrf_crypto_backend_curve25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_curve25519_public_key_t * p_pub =
+ (nrf_crypto_backend_curve25519_public_key_t *)p_public_key;
+
+ // Private key bit fixing is done inside Oberon library.
+ occ_curve25519_scalarmult_base(p_pub->key, p_prv->key);
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_curve25519_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_curve25519_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_curve25519_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&nrf_crypto_internal_swap_endian,
+ //lint -restore
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+// Make sure that common key structure match Ed25519 key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_private_key_t, key) ==
+ offsetof(nrf_crypto_backend_ed25519_private_key_t, private_part),
+ "Common Oberon private key structure does not match Ed25519 one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_public_key_t, key) ==
+ offsetof(nrf_crypto_backend_ed25519_public_key_t, key),
+ "Common Oberon public key structure does not match Ed25519 one.");
+
+
+ret_code_t nrf_crypto_backend_ed25519_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_ed25519_private_key_t * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t *)p_private_key;
+
+ memcpy(p_prv->private_part, p_raw_data, sizeof(p_prv->private_part));
+
+ occ_ed25519_public_key(p_prv->public_part, p_prv->private_part);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_ed25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ ret_code_t result;
+
+ nrf_crypto_backend_ed25519_private_key_t * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_ed25519_public_key_t * p_pub =
+ (nrf_crypto_backend_ed25519_public_key_t *)p_public_key;
+
+ result = oberon_vector_generate(p_prv->private_part, sizeof(p_prv->private_part));
+
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ occ_ed25519_public_key(p_prv->public_part, p_prv->private_part);
+
+ memcpy(p_pub->key, p_prv->public_part, sizeof(p_pub->key));
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_ed25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ nrf_crypto_backend_ed25519_private_key_t * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_ed25519_public_key_t * p_pub =
+ (nrf_crypto_backend_ed25519_public_key_t *)p_public_key;
+
+ memcpy(p_pub->key, p_prv->public_part, sizeof(p_pub->key));
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_ed25519_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_ed25519_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_ed25519_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_ED25519_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_ED25519_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_ED25519_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&memcpy,
+ //lint -restore
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h
new file mode 100644
index 0000000..2fa7d1e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h
@@ -0,0 +1,314 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef OBERON_BACKEND_ECC_H__
+#define OBERON_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+
+/** @internal @brief Generates random number that can be used as a private key for secp256r1.
+ *
+ * It uses RNG from libary frontend to generate random numbers.
+ *
+ * @param[out] data Array where generated random number will be placed.
+ * @returns NRF_SUCCESS or error code passed from RNG frontend.
+ */
+ret_code_t nrf_crypto_backend_oberon_ecc_secp256r1_rng(uint8_t data[32]);
+
+
+/** @internal @brief Structure holding private key for Oberon's secp256r1.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_secp256r1_private_key_t;
+
+
+/** @internal @brief Structure holding public key for Oberon's secp256r1.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[64]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_secp256r1_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp256r1_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+// Common key conversion functions
+#define nrf_crypto_backend_secp256r1_private_key_from_raw \
+ nrf_crypto_backend_oberon_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw \
+ nrf_crypto_backend_oberon_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw \
+ nrf_crypto_backend_oberon_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw \
+ nrf_crypto_backend_oberon_public_key_to_raw
+
+// Free is not required for oberon keys
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+
+// Context is not used in oberon functions
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_CURVE25519)
+#error "More than one backend enabled for Curve25519.");
+#endif
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 1
+
+
+/** @internal @brief Structure holding private key for Oberon's Curve25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key in little endian order. */
+} nrf_crypto_backend_curve25519_private_key_t;
+
+
+/** @internal @brief Structure holding public key for Oberon's Curve25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key in little endian order. */
+} nrf_crypto_backend_curve25519_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_curve25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_curve25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+// Common key conversion functions
+#define nrf_crypto_backend_curve25519_private_key_from_raw \
+ nrf_crypto_backend_oberon_private_key_from_raw
+#define nrf_crypto_backend_curve25519_private_key_to_raw \
+ nrf_crypto_backend_oberon_private_key_to_raw
+#define nrf_crypto_backend_curve25519_public_key_from_raw \
+ nrf_crypto_backend_oberon_public_key_from_raw
+#define nrf_crypto_backend_curve25519_public_key_to_raw \
+ nrf_crypto_backend_oberon_public_key_to_raw
+
+// Free is not required for oberon keys
+#define nrf_crypto_backend_curve25519_private_key_free NULL
+#define nrf_crypto_backend_curve25519_public_key_free NULL
+
+// Context is not used in oberon functions
+#define NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_curve25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_public_key_calculate_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_ED25519)
+#error "More than one backend enabled for Ed25519.");
+#endif
+#define NRF_CRYPTO_ECC_ED25519_ENABLED 1
+
+
+
+/** @internal @brief Structure holding private key for Oberon's Ed25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t private_part[32]; /**< @internal @brief Raw private key. */
+ uint8_t public_part[32]; /**< @internal @brief Raw public key. It is also required for Ed25519 signing. */
+} nrf_crypto_backend_ed25519_private_key_t;
+
+
+/** @internal @brief Structure holding private key for Oberon's Ed25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_ed25519_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_ed25519_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_ed25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_ed25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+// Common key conversion functions
+#define nrf_crypto_backend_ed25519_private_key_to_raw \
+ nrf_crypto_backend_oberon_private_key_to_raw
+#define nrf_crypto_backend_ed25519_public_key_from_raw \
+ nrf_crypto_backend_oberon_public_key_from_raw
+#define nrf_crypto_backend_ed25519_public_key_to_raw \
+ nrf_crypto_backend_oberon_public_key_to_raw
+
+// Free is not required for oberon keys
+#define nrf_crypto_backend_ed25519_private_key_free NULL
+#define nrf_crypto_backend_ed25519_public_key_free NULL
+
+// Context is not used in oberon functions
+#define NRF_CRYPTO_BACKEND_ED25519_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_ED25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_ed25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_ed25519_public_key_calculate_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#endif // OBERON_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c
new file mode 100644
index 0000000..9dcba96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+#include "occ_ecdh_p256.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+#include "occ_curve25519.h"
+#endif
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+ret_code_t nrf_crypto_backend_secp256r1_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_private_key_t const * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_secp256r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t const *)p_public_key;
+
+ result = occ_ecdh_p256_common_secret(p_shared_secret, p_prv->key, p_pub->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+ret_code_t nrf_crypto_backend_curve25519_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ nrf_crypto_backend_curve25519_private_key_t const * p_prv =
+ (nrf_crypto_backend_curve25519_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_curve25519_public_key_t const * p_pub =
+ (nrf_crypto_backend_curve25519_public_key_t const *)p_public_key;
+
+ // Private key can be completely random at this point.
+ // Oberon library updates bits in the key according to Curve25519 specification before use.
+ occ_curve25519_scalarmult(p_shared_secret, p_prv->key, p_pub->key);
+
+ nrf_crypto_internal_swap_endian_in_place(p_shared_secret,
+ NRF_CRYPTO_ECDH_CURVE25519_SHARED_SECRET_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h
new file mode 100644
index 0000000..85dd0d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef OBERON_BACKEND_ECDH_H__
+#define OBERON_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+// Context in not used in OBERON backend
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_curve25519_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+// Context in not used in OBERON backend
+typedef uint32_t nrf_crypto_backend_curve25519_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE 0
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+// ECDH is not possible for Ed25519
+#define nrf_crypto_backend_ed25519_ecdh_compute NULL
+typedef uint32_t nrf_crypto_backend_ed25519_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_ED25519_ECDH_CONTEXT_SIZE 0
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#endif // OBERON_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c
new file mode 100644
index 0000000..5bbfc18
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_ecdsa.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#include "occ_ecdsa_p256.h"
+
+
+#define OBERON_HASH_SIZE_FOR_SECP256R1 (256 / 8)
+
+
+ret_code_t nrf_crypto_backend_secp256r1_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ int result;
+ uint8_t session_key[32];
+
+ nrf_crypto_backend_secp256r1_private_key_t const * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t const *)p_private_key;
+
+ if (data_size < OBERON_HASH_SIZE_FOR_SECP256R1)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ result = nrf_crypto_backend_oberon_ecc_secp256r1_rng(session_key);
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ result = occ_ecdsa_p256_sign_hash(p_signature, p_data, p_prv->key, session_key);
+
+ return result == 0 ? NRF_SUCCESS : NRF_ERROR_CRYPTO_INTERNAL;
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t const *)p_public_key;
+
+ if (data_size < OBERON_HASH_SIZE_FOR_SECP256R1)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ result = occ_ecdsa_p256_verify_hash(p_signature, p_data, p_pub->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+#include "occ_ed25519.h"
+
+
+ret_code_t nrf_crypto_backend_ed25519_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ nrf_crypto_backend_ed25519_private_key_t const * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t const *)p_private_key;
+
+ occ_ed25519_sign(p_signature, p_data, data_size, p_prv->private_part, p_prv->public_part);
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_crypto_backend_ed25519_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_ed25519_public_key_t const * p_pub =
+ (nrf_crypto_backend_ed25519_public_key_t const *)p_public_key;
+
+ result = occ_ed25519_verify(p_signature, p_data, data_size, p_pub->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h
new file mode 100644
index 0000000..070a8cf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef OBERON_BACKEND_ECDSA_H__
+#define OBERON_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_verify_context_t;
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+// Curve25519 is not designed for ECDSA
+#define NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_curve25519_sign_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_verify_context_t;
+#define nrf_crypto_backend_curve25519_sign NULL
+#define nrf_crypto_backend_curve25519_verify NULL
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_ed25519_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_ed25519_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#define NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_ed25519_sign_context_t;
+typedef uint32_t nrf_crypto_backend_ed25519_verify_context_t;
+
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#endif // OBERON_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c
new file mode 100644
index 0000000..cf90e51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "oberon_backend_hash.h"
+#include "crys_hash.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "occ_sha256.h"
+#include "occ_sha512.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+static ret_code_t oberon_backend_hash_sha256_init(void * const p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha256_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ occ_sha256_init(p_backend_context);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t oberon_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha256_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ occ_sha256_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t oberon_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha256_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ occ_sha256_final(p_digest, p_backend_context);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = oberon_backend_hash_sha256_init,
+ .update_fn = oberon_backend_hash_sha256_update,
+ .finalize_fn = oberon_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+
+static ret_code_t oberon_backend_hash_sha512_init(void * p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha512_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ occ_sha512_init(p_backend_context);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hash_sha512_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha512_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ occ_sha512_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hash_sha512_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha512_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ occ_sha512_final(p_digest, p_backend_context);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA512;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info =
+{
+ .init_fn = oberon_backend_hash_sha512_init,
+ .update_fn = oberon_backend_hash_sha512_update,
+ .finalize_fn = oberon_backend_hash_sha512_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha512_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA512
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h
new file mode 100644
index 0000000..534f0ca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef OBERON_BACKEND_HASH_H__
+#define OBERON_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_oberon_backend_hash Oberon backend hash
+ * @{
+ * @ingroup nrf_crypto_oberon_backend
+ *
+ * @brief Hash functionality provided by the Oberon nrf_crypto backend.
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+#include "occ_sha256.h"
+#include "occ_sha512.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-256
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+
+// Flag that SHA-256 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**@brief nrf_crypto_hash context for SHA-256 in nrf_crypto Oberon backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ occ_sha256_ctx context; /**< Hash context internal to Oberon. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-512
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+#error "Duplicate definition of SHA-512. More than one backend enabled");
+#endif
+
+// Flag that SHA-512 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA512_ENABLED 1
+
+
+/**@brief nrf_crypto_hash context for SHA-512 in nrf_crypto Oberon backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ occ_sha512_ctx context; /**< Hash context internal to Oberon. */
+} nrf_crypto_backend_hash_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+/**@} */
+
+#endif // OBERON_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c
new file mode 100644
index 0000000..a89c4ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "nrf_log.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "oberon_backend_hmac.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+#define HMAC_SHA256_BLOCK_SIZE 64
+
+static ret_code_t oberon_backend_hmac_init_sha256(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha256_context_t *)p_context;
+
+ occ_hmac_sha256_init(&p_ctx->oberon_ctx, p_key, key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_update_sha256(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ nrf_crypto_backend_oberon_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha256_context_t *)p_context;
+
+ occ_hmac_sha256_update(&p_ctx->oberon_ctx, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_finalize_sha256(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha256_context_t * const p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha256_context_t *)p_context;
+
+ occ_hmac_sha256_final(p_digest, &p_ctx->oberon_ctx);
+
+ // Assume operation was successful and update the digest size accordingly.
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA256 using Oberon backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info =
+{
+ .init_fn = oberon_backend_hmac_init_sha256,
+ .update_fn = oberon_backend_hmac_update_sha256,
+ .finalize_fn = oberon_backend_hmac_finalize_sha256,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_oberon_hmac_sha256_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA256_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+
+#define HMAC_SHA512_BLOCK_SIZE 128
+
+static ret_code_t oberon_backend_hmac_init_sha512(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha512_context_t *)p_context;
+
+ occ_hmac_sha512_init(&p_ctx->oberon_ctx, p_key, key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_update_sha512(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ nrf_crypto_backend_oberon_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha512_context_t *)p_context;
+
+ occ_hmac_sha512_update(&p_ctx->oberon_ctx, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_finalize_sha512(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha512_context_t * const p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha512_context_t *)p_context;
+
+ occ_hmac_sha512_final(p_digest, &p_ctx->oberon_ctx);
+
+ // Assume operation was successful and update the digest size accordingly.
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA512 using Oberon backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info =
+{
+ .init_fn = oberon_backend_hmac_init_sha512,
+ .update_fn = oberon_backend_hmac_update_sha512,
+ .finalize_fn = oberon_backend_hmac_finalize_sha512,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_oberon_hmac_sha512_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA512_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h
new file mode 100644
index 0000000..d32274f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef OBERON_BACKEND_HMAC_H__
+#define OBERON_BACKEND_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_oberon_backend_hmac Oberon backend for HMAC
+ * @{
+ * @ingroup nrf_crypto_oberon_backend
+ *
+ * @brief Backend wrapper for Oberon. None of these types should be used directly by the
+ * application.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON) && \
+ ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512) )
+
+#include "nrf_crypto_hmac_shared.h"
+#include "occ_hmac_sha256.h"
+#include "occ_hmac_sha512.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NRF_CRYPTO_HMAC_ENABLED
+#define NRF_CRYPTO_HMAC_ENABLED 1
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA256)
+#error "Duplicate definition of HMAC SHA-256. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_HMAC_SHA256_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the Oberon backend wrapper for HMAC SHA256.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha256_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context.
+ occ_hmac_sha256_ctx oberon_ctx; //!< Oberon context object.
+} nrf_crypto_backend_oberon_hmac_sha256_context_t;
+
+
+/**
+ * @internal @brief Context for HMAC SHA256 using Oberon backend.
+ */
+typedef nrf_crypto_backend_oberon_hmac_sha256_context_t nrf_crypto_backend_hmac_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA512)
+#error "Duplicate definition of HMAC SHA-512. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_HMAC_SHA512_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the Oberon backend wrapper for HMAC SHA512.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha512_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context header.
+ occ_hmac_sha512_ctx oberon_ctx; //!< Oberon context object.
+} nrf_crypto_backend_oberon_hmac_sha512_context_t;
+
+/**
+ * @internal @brief Context for HMAC SHA512 using Oberon backend.
+ */
+typedef nrf_crypto_backend_oberon_hmac_sha512_context_t nrf_crypto_backend_hmac_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON && ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256 || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512) )
+
+/**@} */
+
+#endif // OBERON_BACKEND_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h
new file mode 100644
index 0000000..e03ab04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_H__
+#define NRF_CRYPTO_H__
+
+/**
+ * @defgroup nrf_crypto Cryptography library
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Cryptography library (nrf_crypto).
+ *
+ * @details The cryptography library provides cryptographic functionality in a portable way.
+ *
+ * @note The functions in this API can run in software or hardware, depending on the supported features of your SoC and the configuration of nrf_crypto backend in the application.
+ * See @ref lib_crypto_config for details on changing the nrf_crypto backend.
+ *
+ * @}
+ *
+ */
+
+
+
+#include <stdint.h>
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_hash.h"
+#include "nrf_crypto_ecdsa.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_aes.h"
+#include "nrf_crypto_aead.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hkdf.h"
+
+
+#endif // NRF_CRYPTO_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c
new file mode 100644
index 0000000..9459bc6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AEAD)
+
+static ret_code_t context_verify(nrf_crypto_aead_internal_context_t const * p_context)
+{
+ VERIFY_TRUE((p_context != NULL), NRF_ERROR_CRYPTO_CONTEXT_NULL);
+
+ VERIFY_TRUE((p_context->init_value == NRF_CRYPTO_AEAD_INIT_MAGIC_VALUE),
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_aead_init(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_aead_info_t const * const p_info,
+ uint8_t * p_key)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aead_internal_context_t * p_int_context =
+ (nrf_crypto_aead_internal_context_t *)p_context;
+
+ VERIFY_TRUE((p_info != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_key != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_TRUE((ret_val == NRF_SUCCESS) || (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED),
+ ret_val);
+
+ p_int_context->init_value = NRF_CRYPTO_AEAD_INIT_MAGIC_VALUE;
+ p_int_context->p_info = p_info;
+
+ ret_val = p_info->init_fn(p_context, p_key);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ p_int_context->init_value = 0;
+ }
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aead_uninit(void * const p_context)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aead_internal_context_t * p_int_context =
+ (nrf_crypto_aead_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = p_int_context->p_info->uninit_fn(p_context);
+
+ p_int_context->init_value = 0;
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aead_crypt(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aead_internal_context_t * p_int_context =
+ (nrf_crypto_aead_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_FALSE(((p_nonce == NULL) && (nonce_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ /* If mac_size == 0 MAC is updated and not stored under p_mac */
+ VERIFY_FALSE(((p_mac == NULL) && (mac_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_FALSE(((p_adata == NULL) && (adata_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_FALSE(((p_data_in == NULL) && (data_in_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_FALSE(((p_data_out == NULL) && (data_in_size != 0)),
+ NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ ret_val = p_int_context->p_info->crypt_fn(p_context,
+ operation,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ data_in_size,
+ p_data_out,
+ p_mac,
+ mac_size);
+ return ret_val;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h
new file mode 100644
index 0000000..a0de689
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AEAD_H__
+#define NRF_CRYPTO_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aead AEAD (Authenticated Encryption with Associated Data) related
+ * functions.
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AEAD related functionality through nrf_crypto.
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+#include "nrf_crypto_aead_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief External variable declaration to the info structure for AES CCM mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_128_info;
+
+/**@brief External variable declaration to the info structure for AES CCM mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_192_info;
+
+/**@brief External variable declaration to the info structure for AES CCM mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_256_info;
+
+/**@brief External variable declaration to the info structure for AES CCM* mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_star_128_info;
+
+/**@brief External variable declaration to the info structure for AES EAX mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_eax_128_info;
+
+/**@brief External variable declaration to the info structure for AES EAX mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_eax_192_info;
+
+/**@brief External variable declaration to the info structure for AES EAX mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_eax_256_info;
+
+/**@brief External variable declaration to the info structure for AES GCM mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_gcm_128_info;
+
+/**@brief External variable declaration to the info structure for AES GCM mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_gcm_192_info;
+
+/**@brief External variable declaration to the info structure for AES GCM mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_gcm_256_info;
+
+/**@brief External variable declaration to the info structure for CHACHA-POLY mode with a 256-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_chacha_poly_256_info;
+
+
+/**
+ * @brief Context type for AEAD.
+ *
+ * @note The size of this type is scaled for the largest AEAD backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_aead_context_t nrf_crypto_aead_context_t;
+
+
+/**@brief Function for initializing the AEAD calculation context.
+ *
+ * @param[in] p_context Pointer to the context object. It must be a context type associated with
+ * the object provided in the p_info parameter or other memory that can
+ * hold that context type.
+ * @param[in] p_info Pointer to structure holding information about: selected AES AEAD mode,
+ * and key size.
+ * @param[in] p_key Pointer to AEAD mode key.
+ *
+ * @retval NRF_SUCCESS Context was successfully initialized.
+ */
+ret_code_t nrf_crypto_aead_init(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_aead_info_t const * const p_info,
+ uint8_t * p_key);
+
+/**@brief Function for uninitializing the AEAD calculation context.
+ *
+ * @param[in] p_context Pointer to the context object. It must be initialized before function call.
+ *
+ * @retval NRF_SUCCESS Context was successfully uninitialized.
+ */
+ret_code_t nrf_crypto_aead_uninit(void * const p_context);
+
+/**@brief Integrated encryption / decryption function.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] operation Parameter indicating whether an encrypt (NRF_CRYPTO_ENCRYPT) or
+ * a decrypt (NRF_CRYPTO_DECRYPT) operation shall be performed.
+ * @param[in] p_nonce Pointer to nonce. For nonce_size == 0 p_nonce can be NULL.
+ * @param[in] nonce_size Nonce byte size. Valid values for supported modes:
+ * - CCM [7 ... 13]
+ * - CCM* [13]
+ * - EAX nonce size can be any length
+ * - GCM nonce size can be any length
+ * - CHACHA-POLY [12]
+ * @param[in] p_adata Pointer to additional authenticated data (adata).
+ * @param[in] adata_size Length of additional authenticated data in bytes.
+ * For CHACHA-POLY mode must be > 0.
+ * @param[in] p_data_in Pointer to the input data buffer for encryption or decryption.
+ * @param[in] data_in_size Length of the data in p_data_in buffer in bytes. Size of the
+ * p_data_out buffer must not be smaller than this value.
+ * When selecting CC310 backend data_in_size value shall be limited
+ * to 65535 bytes. Data out buffer must be at least the same length.
+ * @param[out] p_data_out Pointer to the output buffer where encrypted or decrypted data
+ * will be stored. Must be at least 'data_in_size' bytes wide.
+ * - GCM: On encryption, the p_data_out buffer can be the same as
+ * the p_data_in buffer.
+ * On decryption, the p_data_out buffer cannot be the same
+ * as p_data_in buffer. If buffers overlap, the p_data_out
+ * buffer must trail at least 8 bytes behind the p_data_in
+ * buffer.
+ * @param[out] p_mac Pointer to the MAC result buffer. Fo mac_size == 0 p_mac can be NULL.
+ * @param[in] mac_size MAC byte size. Valid values for supported modes:
+ * -CCM [4, 6, 8, 10, 12, 14, 16]
+ * -CCM* [0, 4, 8, 16]
+ * -EAX [1 ... 16]
+ * -GCM [4 ... 16]
+ * -CHACHA-POLY [16]
+ *
+ * @retval NRF_SUCCESS Message was successfully encrypted.
+ */
+ret_code_t nrf_crypto_aead_crypt(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+/** @} */
+
+#endif // NRF_CRYPTO_AEAD_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h
new file mode 100644
index 0000000..fd792dd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AEAD_BACKEND_H__
+#define NRF_CRYPTO_AEAD_BACKEND_H__
+
+#include "cc310_backend_aes_aead.h"
+#include "cc310_backend_chacha_poly_aead.h"
+#include "cifra_backend_aes_aead.h"
+#include "mbedtls_backend_aes_aead.h"
+#include "oberon_backend_chacha_poly_aead.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Fallback type for AES CCM context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_ccm_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CCM* context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM_STAR)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_ccm_star_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES EAX context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_EAX)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_eax_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES GCM context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_GCM)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_gcm_context_t;
+#endif
+
+/**@internal @brief Fallback type for CHACHA-POLY context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_CHACHA_POLY)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_chacha_poly_context_t;
+#endif
+
+/** @internal @brief Union holding a AEAD context. */
+typedef union
+{
+ nrf_crypto_backend_aes_ccm_context_t ccm_context; /**< @brief Holds context for AES CCM. */
+ nrf_crypto_backend_aes_ccm_star_context_t ccm_star_context; /**< @brief Holds context for AES CCM*. */
+ nrf_crypto_backend_aes_eax_context_t eax_context; /**< @brief Holds context for AES EAX. */
+ nrf_crypto_backend_aes_gcm_context_t gcm_context; /**< @brief Holds context for AES GCM. */
+
+ nrf_crypto_backend_chacha_poly_context_t chacha_poly_context; /**< @brief Holds context for ChaCha-Poly. */
+} nrf_crypto_backend_aead_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_AEAD_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h
new file mode 100644
index 0000000..f847c1e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AEAD_SHARED_H__
+#define NRF_CRYPTO_AEAD_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aead_shared AEAD related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AEAD related functionality through nrf_crypto.
+ */
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Magic value to signal that the nrf_crypto_hash context structure is initialized.
+ */
+#define NRF_CRYPTO_AEAD_INIT_MAGIC_VALUE (0x44414541) // ASCII "AEAD"
+
+#define NRF_CRYPTO_AES_CCM_STAR_MAC_BITMASK (0x1C) /* [0, 4, 8, 16] allowed MAC size in CCM mode */
+#define NRF_CRYPTO_AES_CCM_MAC_MIN (4u) /* MAC min value in CCM mode */
+#define NRF_CRYPTO_AES_CCM_MAC_MAX (16u) /* MAC max value in CCM mode */
+#define NRF_CRYPTO_AES_GCM_MAC_MIN (4u) /* MAC min value in GCM mode */
+#define NRF_CRYPTO_AES_GCM_MAC_MAX (16u) /* MAC max value in GCM mode */
+#define NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN (7u) /* [7...13] allowed nonce size in CCM mode */
+#define NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX (13u) /* [7...13] allowed nonce size in CCM mode */
+#define NRF_CRYPTO_AES_CCM_STAR_NONCE_SIZE (13u) /* [13] allowed nonce size in CCM* mode */
+#define NRF_CRYPTO_CHACHA_POLY_NONCE_SIZE (12u) /* [12] allowed nonce size in chacha-poly mode */
+#define NRF_CRYPTO_CHACHA_POLY_MAC_SIZE (16u) /* [16] allowed MAC size in chacha-poly mode */
+
+/**@internal @brief Enumeration of supported modes of operation in nrf_crypto_aead.
+ */
+typedef enum
+{
+ NRF_CRYPTO_AEAD_MODE_AES_CCM, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AEAD_MODE_AES_CCM_STAR, // supported by: CC310
+ NRF_CRYPTO_AEAD_MODE_AES_EAX, // supported by: CIFRA
+ NRF_CRYPTO_AEAD_MODE_AES_GCM, // supported by: MBEDTLS
+ NRF_CRYPTO_AEAD_MODE_CHACHA_POLY // supported by: CC310 & OBERON
+} nrf_crypto_aead_mode_t;
+
+
+/**@internal @brief Type declaration to perform AEAD initialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aead_init for documentation.
+ */
+typedef ret_code_t (*aead_init_fn_t)(void * const p_context, uint8_t * p_key);
+
+/**@internal @brief Type declaration to perform AEAD uninitialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aead_uninit for documentation.
+ */
+typedef ret_code_t (*aead_uninit_fn_t)(void * const p_context);
+
+/**@internal @brief Type declaration to perform AEAD encryption in nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aead_crypt for documentation.
+ */
+typedef ret_code_t (*aead_crypt_fn_t)(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size);
+
+/**@internal @brief Type declaration for the nrf_crypto_aead info structure.
+ *
+ * @details This structure contains the calling interface and any metadata required
+ * to call the nrf_crypto_aead API functions.
+ */
+typedef struct
+{
+ nrf_crypto_aead_mode_t const mode;
+ nrf_crypto_key_size_id_t const key_size;
+
+ aead_init_fn_t const init_fn;
+ aead_uninit_fn_t const uninit_fn;
+ aead_crypt_fn_t const crypt_fn;
+} nrf_crypto_aead_info_t;
+
+/**@internal @brief Type declaration of internal representation of an AEAD context structure.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value;
+ nrf_crypto_aead_info_t const * p_info;
+} nrf_crypto_aead_internal_context_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef NRF_CRYPTO_AEAD_SHARED_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c
new file mode 100644
index 0000000..f2ac8ae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c
@@ -0,0 +1,319 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_aes.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_aes_shared.h"
+#include "nrf_crypto_aes_backend.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES)
+
+static ret_code_t context_verify(nrf_crypto_aes_internal_context_t const * p_context)
+{
+ if (p_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ }
+
+ if (p_context->init_value != NRF_CRYPTO_AES_INIT_MAGIC_VALUE)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_crypto_aes_init(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_TRUE((ret_val == NRF_SUCCESS) || (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED),
+ ret_val);
+
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ p_int_context->p_info = p_info;
+
+ ret_val = p_info->init_fn(p_context, operation);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ p_int_context->init_value = NRF_CRYPTO_AES_INIT_MAGIC_VALUE;
+ }
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_uninit(nrf_crypto_aes_context_t * const p_context)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+
+ if (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED)
+ {
+ /* If context was uninitialized with function nrf_crypto_aes_finalize it shall be still
+ possible to clear init_value */
+ if (p_int_context->init_value == NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE)
+ {
+ ret_val = NRF_SUCCESS;
+ }
+ }
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = p_int_context->p_info->uninit_fn(p_context);
+
+ p_int_context->init_value = 0;
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_key_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_key)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_key != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ ret_val = p_int_context->p_info->key_set_fn(p_context, p_key);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_iv_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_int_context->p_info->iv_set_fn != NULL), NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ VERIFY_TRUE((p_iv != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ ret_val = p_int_context->p_info->iv_set_fn(p_context, p_iv);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_iv_get(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ if (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED)
+ {
+ /* If context was uninitialized with function nrf_crypto_aes_finalize it shall be still
+ possible to read IV value */
+ if (p_int_context->init_value == NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE)
+ {
+ ret_val = NRF_SUCCESS;
+ }
+ }
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_iv != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_int_context->p_info->iv_get_fn != NULL), NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ ret_val = p_int_context->p_info->iv_get_fn(p_context, p_iv);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_update(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((data_size != 0), NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ VERIFY_TRUE((p_data_in != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_data_out != NULL), NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ if ((data_size & 0xF) != 0)
+ {
+ VERIFY_TRUE((p_int_context->p_info->mode == NRF_CRYPTO_AES_MODE_CFB),
+ NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ }
+
+ ret_val = p_int_context->p_info->update_fn(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_finalize(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_data_in != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_data_out != NULL), NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ VERIFY_TRUE((p_data_out_size != NULL), NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ ret_val = p_int_context->p_info->finalize_fn(p_context,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+
+ VERIFY_TRUE((ret_val == NRF_SUCCESS), ret_val);
+
+ ret_val = nrf_crypto_aes_uninit(p_context);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ /* This line will allow to read IV for AES supporting IV get function. */
+ p_int_context->init_value = NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE;
+ }
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_crypt(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_key,
+ uint8_t * p_iv,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ void * p_allocated_context = NULL;
+
+ nrf_crypto_aes_context_t * p_ctx = p_context;
+
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ if (p_ctx == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = (nrf_crypto_aes_context_t *)p_allocated_context;
+ }
+
+ ret_val = nrf_crypto_aes_init(p_ctx, p_info, operation);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_aes_key_set(p_ctx, p_key);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_aes_iv_set(p_ctx, p_iv);
+ /* not all AES modes support IV */
+ if (ret_val != NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE)
+ {
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+ }
+
+ ret_val = nrf_crypto_aes_finalize(p_ctx,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+ if (ret_val != NRF_SUCCESS)
+ {
+ /* Context was not successfully deinitialized in nrf_crypto_aes_finalize */
+ UNUSED_RETURN_VALUE(nrf_crypto_aes_uninit(p_ctx));
+ }
+
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return ret_val;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_AES)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h
new file mode 100644
index 0000000..bb02700
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h
@@ -0,0 +1,481 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AES_H__
+#define NRF_CRYPTO_AES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aes AES related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AES related functionality through nrf_crypto.
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aes_shared.h"
+#include "nrf_crypto_aes_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 128-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_128_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 192-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_192_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 256-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_256_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 128-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_128_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 192-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_192_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 256-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_256_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CTR mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ctr_128_info;
+
+/**@brief External variable declaration to the info structure for AES CTR mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ctr_192_info;
+
+/**@brief External variable declaration to the info structure for AES CTR mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ctr_256_info;
+
+/**@brief External variable declaration to the info structure for AES CFB mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cfb_128_info;
+
+/**@brief External variable declaration to the info structure for AES CFB mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cfb_192_info;
+
+/**@brief External variable declaration to the info structure for AES CFB mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cfb_256_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 128-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_128_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 192-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_192_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 256-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_256_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 128-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_128_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 192-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_192_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 256-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_256_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 128-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_128_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 192-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_192_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 256-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_256_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 128-bit
+* key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_128_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 192-bit
+* key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_192_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 256-bit
+* key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_256_pad_pkcs7_info;
+
+
+/**@brief External variable declaration to the info structure for AES CMAC mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cmac_128_info;
+
+/**@brief External variable declaration to the info structure for AES CMAC mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cmac_192_info;
+
+/**@brief External variable declaration to the info structure for AES CMAC mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cmac_256_info;
+
+/**
+ * @brief Context type for AES.
+ *
+ * @note The size of this type is scaled for the largest AES backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_aes_context_t nrf_crypto_aes_context_t;
+
+/**@brief Function for initializing the AES context.
+ *
+ * @param[in] p_context Pointer to the context object. It must be a context type associated
+ * with the object provided in the p_info parameter or other memory
+ * that can hold that context type.
+ * @param[in] p_info Pointer to structure holding information about: selected AES mode,
+ * key size, and padding.
+ * @param[in] operation Parameter indicating whether an encrypt (NRF_CRYPTO_ENCRYPT),
+ * a decrypt (NRF_CRYPTO_DECRYPT) or MAC calculation
+ * (NRF_CRYPTO_MAC_CALCULATE) operation shall be performed.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_init(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation);
+
+/**@brief Internal function for uninitializing the AES context.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_uninit(nrf_crypto_aes_context_t * const p_context);
+
+/**@brief Function for setting the AES key.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_key Pointer to the AES key. This buffer will be copied and there is no need
+ * to keep it by the user.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_key_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_key);
+
+/**@brief Function for setting an AES IV or a counter for AES modes which are using it.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_iv Pointer to a buffer of the IV or a counter. This buffer will be copied
+ * and there is no need to keep it by the user.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_iv_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv);
+
+/**@brief Function for getting an AES IV or a counter for mode which is supporting it.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[out] p_iv Pointer to a buffer of the IV or a counter.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_iv_get(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv);
+
+/**@brief AES update function for encryption, decryption and MAC calculation. It can be called once
+ * on the whole data block, or as many times as needed, until all the input data is processed.
+ * Functions: @ref nrf_crypto_aes_init, @ref nrf_crypto_aes_key_set, and, for some ciphers,
+ * @ref nrf_crypto_aes_iv_set, must be called before call to this API with the same context.
+
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_data_in Pointer to the input buffer to the AES.
+ * @param[in] data_size Size of the data to be processed in bytes.
+ * For all modes except CFB it must be multiple of 16 bytes.
+ * @param[out] p_data_out Pointer to the output buffer.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_update(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out);
+
+
+/**@brief Function processes the last data block if needed and finalizes the AES operation (ie. adds
+ * padding) and produces operation results (for MAC operations).
+ * Functions: @ref nrf_crypto_aes_init, @ref nrf_crypto_aes_key_set, and, for some ciphers,
+ * @ref nrf_crypto_aes_iv_set, must be called before call to this API with the same context.
+ *
+ * Upon successful operation function will deinitialize the context but for some ciphers it will be
+ * possible to read IV. In order to fully deinitialize context you must call
+ * @ref nrf_crypto_aes_uninit.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_data_in Pointer to the input buffer to the AES.
+ * @param[in] data_size Size of the data to be processed in bytes.
+ * @param[out] p_data_out Pointer to the output buffer.
+ * When padding is set:
+ * - The size of p_data_out buffer must have extra space for
+ * padding. Otherwise, the function will return an error:
+ * NRF_ERROR_CRYPTO_OUTPUT_LENGTH.
+ * - When text_size is multiple of 16 bytes, p_text_out must be
+ * allocated with size equal to text_size + an additional block
+ * (i.e 16 bytes for padding).
+ * - When text_size is not a multiple of 16 bytes, p_text_out
+ * must be allocated with size aligned to the next full 16
+ * bytes block (i.e. 1 - 15 bytes for padding).
+ * @param[in,out] p_data_out_size IN:
+ * Size of the p_data_out buffer.
+ * OUT:
+ * Upon successfull function execution value will be updated
+ * with number of signifacnt bytes in p_data_out buffer.
+ * On decryption with padding function will result in a value
+ * without padded bytes.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_finalize(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size);
+
+
+
+
+/**@brief AES integrated function for encryption, decryption and MAC calculation.
+ * It should be called once on the whole data block.
+ *
+ * @param[in] p_context Context object. If NULL, memory will be dynamically allocated.
+ * @param[in] p_info Pointer to structure holding information about: selected AES
+ * mode, key size, and padding.
+ * @param[in] operation Parameter indicating whether an encrypt (NRF_CRYPTO_ENCRYPT),
+ * a decrypt (NRF_CRYPTO_DECRYPT) or MAC calculation
+ * (NRF_CRYPTO_MAC_CALCULATE) operation shall be performed.
+ * @param[in] p_key Pointer to the AES key. This buffer will be copied and there is
+ * no need to keep it by the user.
+ * @param[in] p_iv Pointer to a buffer of the IV or a counter. This buffer will be
+ * copied and there is no need to keep it by the user.
+ * Can be NULL for ECB and CMAC.
+ * @param[in] p_data_in Pointer to the input buffer to the AES.
+ * @param[in] data_size Size of the data to be processed in bytes.
+ * @param[out] p_data_out Pointer to the output buffer.
+ * When padding is set:
+ * - The size of p_data_out buffer must have extra space for
+ * padding. Otherwise, the function will return an error:
+ * NRF_ERROR_CRYPTO_OUTPUT_LENGTH.
+ * - When text_size is multiple of 16 bytes, p_text_out must be
+ * allocated with size equal to text_size + an additional block
+ * (i.e 16 bytes for padding).
+ * - When text_size is not a multiple of 16 bytes, p_text_out
+ * must be allocated with size aligned to the next full 16
+ * bytes block (i.e. 1 - 15 bytes for padding).
+ * @param[in,out] p_data_out_size IN:
+ * Size of the p_data_out buffer.
+ * OUT:
+ * Upon successfull function execution value will be updated
+ * with number of signifacnt bytes in p_data_out buffer.
+ * On decryption function will result in a value without padded
+ * bytes.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_crypt(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_key,
+ uint8_t * p_iv,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+/** @} */
+
+#endif // #ifndef NRF_CRYPTO_AES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h
new file mode 100644
index 0000000..5c34476
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AES_BACKEND_H__
+#define NRF_CRYPTO_AES_BACKEND_H__
+
+#include "cc310_backend_aes.h"
+#include "mbedtls_backend_aes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Fallback type for AES CBC context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cbc_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CFB context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CFB)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cfb_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CTR context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CTR)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_ctr_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES ECB context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_ECB)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_ecb_context_t;
+#endif
+
+
+/**@internal @brief Fallback type for AES CBC_MAC context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC_MAC)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cbc_mac_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CMAC context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cmac_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CMAC_PRF128 context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC_PRF128)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cmac_prf128_context_t;
+#endif
+
+
+/** @internal @brief Union holding a AES context. */
+typedef union
+{
+ nrf_crypto_backend_aes_cbc_context_t cbc_context; /**< @brief Holds context for AES CBC. */
+ nrf_crypto_backend_aes_cfb_context_t cfb_context; /**< @brief Holds context for AES CFB. */
+ nrf_crypto_backend_aes_ctr_context_t ctr_context; /**< @brief Holds context for AES CFB. */
+ nrf_crypto_backend_aes_ecb_context_t ecb_context; /**< @brief Holds context for AES ECB. */
+
+ nrf_crypto_backend_aes_cbc_mac_context_t cbc_mac_context; /**< @brief Holds context for CBC-MAC. */
+ nrf_crypto_backend_aes_cmac_context_t cmac_context; /**< @brief Holds context for CMAC. */
+ nrf_crypto_backend_aes_cmac_prf128_context_t cmac_prf128_context; /**< @brief Holds context for CMAC_PRF128. */
+} nrf_crypto_backend_aes_context_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_AES_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c
new file mode 100644
index 0000000..615b236
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "sdk_config.h"
+#include "nrf_crypto_types.h"
+
+
+ret_code_t padding_pkcs7_add(uint8_t * p_padding_buff,
+ uint8_t * p_message_buff,
+ uint8_t msg_ending_len)
+{
+ uint8_t padding_count;
+
+ if ((p_padding_buff == NULL) || (p_message_buff == NULL))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_NULL;
+ }
+
+ if (msg_ending_len >= NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ /* Creating padding buffer in two steps */
+ /* step 1 add remaining message */
+ memcpy(p_padding_buff, p_message_buff, msg_ending_len);
+
+ /* step 2: add padding */
+ padding_count = NRF_CRYPTO_AES_BLOCK_SIZE - msg_ending_len;
+ p_padding_buff += msg_ending_len;
+
+ for (size_t i = 0; i < padding_count; i++)
+ {
+ p_padding_buff[i] = padding_count;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t padding_pkcs7_remove(uint8_t * p_padded_message,
+ size_t * p_message_len)
+{
+ if (p_padded_message == NULL)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_NULL;
+ }
+ if (p_message_len == NULL)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ }
+
+ /* padded_msg_len must be multiple of 16 */
+ if ((*p_message_len == 0) || ((*p_message_len & 0x0F) != 0))
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ size_t padded_bytes = p_padded_message[*p_message_len - 1];
+
+ if ((padded_bytes == 0) || (padded_bytes > NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ return NRF_ERROR_CRYPTO_AES_INVALID_PADDING;
+ }
+
+ /* i = 2: 1 for valid string and 1 for already checked *p_message_len - 1 */
+ for (size_t i = 2; i < padded_bytes; i++)
+ {
+ if (p_padded_message[*p_message_len - i] != padded_bytes)
+ {
+ return NRF_ERROR_CRYPTO_AES_INVALID_PADDING;
+ }
+ }
+
+ *p_message_len -= padded_bytes;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h
new file mode 100644
index 0000000..9878bcb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AES_SHARED_H__
+#define NRF_CRYPTO_AES_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aes AES related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AES related functionality through nrf_crypto.
+ */
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@internal @brief Magic value to signal that the nrf_crypto_hash context structure is initialized.
+ */
+#define NRF_CRYPTO_AES_INIT_MAGIC_VALUE (0x53454163) // ASCII "cAES"
+#define NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE (0x63414553) // ASCII "SEAc"
+
+#define NRF_CRYPTO_MBEDTLS_AES_IV_SIZE (16)
+
+
+/** @internal @brief Enumeration of supported modes of operation in nrf_crypto_aes.
+ */
+typedef enum
+{
+ NRF_CRYPTO_AES_MODE_CBC, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CFB, // supported by: MBEDTLS
+ NRF_CRYPTO_AES_MODE_CTR, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_ECB, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7, // supported by: MBEDTLS & CC310
+
+ // Authentication modes
+ NRF_CRYPTO_AES_MODE_CBC_MAC, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CMAC, // supported by: MBEDTLS & CC310
+} nrf_crypto_aes_mode_t;
+
+/**@internal @brief Type declaration to perform AES initialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_init for documentation.
+ */
+typedef ret_code_t (*aes_init_fn_t)(void * const p_context, nrf_crypto_operation_t operation);
+
+/**@internal @brief Type declaration to perform AES uninitialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_uninit for documentation.
+ */
+typedef ret_code_t (*aes_uninit_fn_t)(void * const p_context);
+
+/**@internal @brief Type declaration to set an AES key in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_key_set for documentation.
+ */
+typedef ret_code_t (*aes_key_set_fn_t)(void * const p_context, uint8_t * p_key);
+
+/**@internal @brief Type declaration to set an AES IV in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_iv_set for documentation.
+ */
+typedef ret_code_t (*aes_iv_set_fn_t)(void * const p_context, uint8_t * p_iv);
+
+/**@internal @brief Type declaration to get an AES IV in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_iv_get for documentation.
+ */
+typedef ret_code_t (*aes_iv_get_fn_t)(void * const p_context, uint8_t * p_iv);
+
+/**@internal @brief Type declaration to perform AES block operation in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_update for documentation.
+ */
+typedef ret_code_t (*aes_update_fn_t)(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out);
+
+/**@internal @brief Type declaration to finalize AES operation in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_finalize for documentation.
+ */
+typedef ret_code_t (*aes_finalize_fn_t)(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size);
+
+/**@internal @brief Type declaration for an nrf_crypto_aes info structure.
+ *
+ * @details This structure contains the calling interface and any metadata required
+ * to call the nrf_crypto_aes API functions.
+ */
+typedef struct
+{
+ nrf_crypto_aes_mode_t const mode;
+ nrf_crypto_key_size_id_t const key_size;
+ size_t const context_size;
+
+ aes_init_fn_t const init_fn;
+ aes_uninit_fn_t const uninit_fn;
+ aes_key_set_fn_t const key_set_fn;
+ aes_iv_set_fn_t const iv_set_fn;
+ aes_iv_get_fn_t const iv_get_fn;
+ aes_update_fn_t const update_fn;
+ aes_finalize_fn_t const finalize_fn;
+} nrf_crypto_aes_info_t;
+
+/**@internal @brief Type declaration of internal representation of an AES context structure.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value;
+ nrf_crypto_aes_info_t const * p_info;
+} nrf_crypto_aes_internal_context_t;
+
+
+/**@internal @brief Type declaration of internal representation of an AES backend context structure.
+ * with initialization vector.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ nrf_crypto_operation_t operation;
+
+ uint8_t iv[NRF_CRYPTO_MBEDTLS_AES_IV_SIZE]; // space for 128-bit initialization vector
+} nrf_crypto_backend_aes_ctx_t;
+
+/**@internal @brief Type declaration of internal representation of an AES backend context structure
+ * without initialization vector.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ nrf_crypto_operation_t operation;
+} nrf_crypto_backend_no_iv_aes_ctx_t;
+
+
+/**@internal @brief Function copies remainders (msg_ending_len) from p_message_buff to the
+ * p_padding_buff. Next it adds pkcs7-padding to have a 16 bytes p_padding_buff.
+ *
+ * @param[in] p_padding_buff Pointer the buffer with padded message.
+ * @param[in] p_message_buff Pointer to the buffer with message that must be padded.
+ * @param[in] msg_ending_len Message remainders length.
+ *
+ */
+ret_code_t padding_pkcs7_add(uint8_t * p_padding_buff,
+ uint8_t * p_message_buff,
+ uint8_t msg_ending_len);
+
+
+/**@internal @brief Function calculate message length without padding.
+ *
+ * @param[in] p_padded_message Pointer the buffer with padded message.
+ * @param[in/out] p_message_len IN: padded message length
+ * OUT: message length without padding
+ */
+ret_code_t padding_pkcs7_remove(uint8_t * p_padded_message,
+ size_t * p_message_len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // #ifndef NRF_CRYPTO_AES_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c
new file mode 100644
index 0000000..8bff9a7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c
@@ -0,0 +1,1314 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nordic_common.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+
+#if NRF_CRYPTO_ECC_ENABLED
+
+
+#if NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT > 1
+
+
+static const nrf_crypto_backend_ecc_key_pair_generate_fn_t key_pair_generate_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_key_pair_generate,
+#endif
+};
+
+
+static const uint16_t key_pair_generate_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_public_key_calculate_fn_t public_key_calculate_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_calculate,
+#endif
+};
+
+
+static const uint16_t public_key_calculate_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_private_key_from_raw_fn_t private_key_from_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_private_key_from_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_private_key_to_raw_fn_t private_key_to_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_private_key_to_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_public_key_from_raw_fn_t public_key_from_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_from_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_public_key_to_raw_fn_t public_key_to_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_to_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_key_free_fn_t private_key_free_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_private_key_free,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_key_free_fn_t public_key_free_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_free,
+#endif
+};
+
+
+#define BACKEND_IMPL_GET(table, curve_type) (table)[(uint32_t)(curve_type)]
+
+
+#else
+
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp160r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp160r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp160r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp160r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp160r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp160r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp160r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp160r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160R2_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp160r2_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp160r2_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp160r2_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp160r2_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp160r2_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp160r2_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp160r2_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp160r2_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R2_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R2_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp192r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp192r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp192r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp192r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp192r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp192r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp192r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp192r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp224r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp224r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp224r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp224r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp224r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp224r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp224r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp224r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp256r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp256r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp256r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp256r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp256r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp256r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp256r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp256r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP384R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp384r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp384r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp384r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp384r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp384r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp384r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp384r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp384r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP521R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp521r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp521r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp521r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp521r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp521r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp521r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp521r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp521r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp160k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp160k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp160k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp160k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp160k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp160k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp160k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp160k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp192k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp192k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp192k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp192k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp192k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp192k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp192k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp192k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp224k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp224k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp224k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp224k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp224k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp224k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp224k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp224k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp256k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp256k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp256k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp256k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp256k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp256k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp256k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp256k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_bp256r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_bp256r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_bp256r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_bp256r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_bp256r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_bp256r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_bp256r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_bp256r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_BP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_BP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_bp384r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_bp384r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_bp384r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_bp384r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_bp384r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_bp384r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_bp384r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_bp384r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_BP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_BP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_bp512r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_bp512r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_bp512r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_bp512r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_bp512r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_bp512r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_bp512r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_bp512r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_BP512R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_BP512R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_curve25519_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_curve25519_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_curve25519_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_curve25519_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_curve25519_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_curve25519_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_curve25519_private_key_free
+#define public_key_free_impl nrf_crypto_backend_curve25519_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_ED25519_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_ed25519_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_ed25519_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_ed25519_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_ed25519_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_ed25519_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_ed25519_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_ed25519_private_key_free
+#define public_key_free_impl nrf_crypto_backend_ed25519_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_ED25519_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_ED25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#else
+#define key_pair_generate_impl NULL
+#define public_key_calculate_impl NULL
+#define private_key_from_raw_impl NULL
+#define private_key_to_raw_impl NULL
+#define public_key_from_raw_impl NULL
+#define public_key_to_raw_impl NULL
+#define private_key_free_impl NULL
+#define public_key_free_impl NULL
+#define key_pair_generate_context_size 0
+#define public_key_calculate_context_size 0
+#endif
+
+
+#define BACKEND_IMPL_GET(function, curve_type) (function)
+
+
+#endif
+
+
+ret_code_t nrf_crypto_internal_ecc_key_output_prepare(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_internal_ecc_key_header_t * p_key_header)
+{
+ // Check NULL pointers
+ VERIFY_TRUE(p_curve_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_key_header != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ // Clear init value to indicate that this key is not valid yet.
+ p_key_header->init_value = 0;
+ // Save curve info inside the header
+ p_key_header->p_info = p_curve_info;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_internal_ecc_key_input_check(
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header,
+ uint32_t init_value)
+{
+ // Check NULL pointer
+ VERIFY_TRUE(p_key_header != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ // Check init value
+ VERIFY_TRUE(p_key_header->init_value == init_value, NRF_ERROR_CRYPTO_ECC_KEY_NOT_INITIALIZED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_internal_ecc_raw_output_prepare(
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size,
+ size_t expected_size)
+{
+ // Check NULL pointer
+ VERIFY_TRUE(p_raw_data != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ if (p_raw_data_size != NULL) // User can provide NULL as p_raw_data_size to skip size checking
+ {
+ // Check if data fits into buffer
+ VERIFY_TRUE(*p_raw_data_size >= expected_size, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+ // Provide actual data size
+ *p_raw_data_size = expected_size;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_internal_ecc_raw_input_check(
+ uint8_t const * p_raw_data,
+ size_t raw_data_size,
+ size_t expected_size)
+{
+ VERIFY_TRUE(p_raw_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(raw_data_size == expected_size, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_ecc_key_pair_generate(
+ nrf_crypto_ecc_key_pair_generate_context_t * p_context,
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecc_key_pair_generate_fn_t backend_implementation;
+ size_t context_size;
+
+ // Get pointer to header for each key
+ nrf_crypto_internal_ecc_key_header_t * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_private_key;
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info, p_private_key_header);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info, p_public_key_header);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(key_pair_generate_impl, p_curve_info->curve_type);
+ context_size = BACKEND_IMPL_GET(key_pair_generate_context_size, p_curve_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_public_key);
+
+ // Set init values to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_private_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE;
+ p_public_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE;
+ }
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_calculate(
+ nrf_crypto_ecc_public_key_calculate_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecc_public_key_calculate_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header for each key
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_info, p_public_key_header);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_calculate_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(public_key_calculate_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_public_key);
+
+ // Set init values to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_public_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE;
+ }
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_private_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_backend_ecc_private_key_from_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_private_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info,
+ p_private_key_header);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_raw_input_check(p_raw_data,
+ raw_data_size,
+ p_curve_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(private_key_from_raw_impl, p_curve_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_private_key, p_raw_data);
+
+ // Set init value to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_private_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE;
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_private_key_to_raw(
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_private_key_to_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(p_raw_data,
+ p_raw_data_size,
+ p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(private_key_to_raw_impl, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_private_key, p_raw_data);
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_public_key_t * p_public_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_backend_ecc_private_key_from_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info,
+ p_public_key_header);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_raw_input_check(p_raw_data,
+ raw_data_size,
+ p_curve_info->raw_public_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_from_raw_impl, p_curve_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_public_key, p_raw_data);
+
+ // Set init value to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_public_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE;
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_to_raw(
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_public_key_to_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_public_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(p_raw_data,
+ p_raw_data_size,
+ p_info->raw_public_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_to_raw_impl, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_public_key, p_raw_data);
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_private_key_free(
+ nrf_crypto_ecc_private_key_t * p_private_key)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_key_free_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_private_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+
+ UNUSED_PARAMETER(p_info); // Is some situations BACKEND_IMPL_GET() macro may not use second parameter
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(private_key_free_impl, p_info->curve_type);
+
+ if (backend_implementation != NULL)
+ {
+ // Execute backend implementation
+ result = backend_implementation(p_private_key);
+ }
+ else
+ {
+ // Free is not implemented by the backend, so nothing have to deallocated.
+ result = NRF_SUCCESS;
+ }
+
+ // Clear init value to indicate invalid key
+ p_private_key_header->init_value = 0;
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_free(
+ nrf_crypto_ecc_public_key_t * p_public_key)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_key_free_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_public_key_header->p_info;
+
+ UNUSED_PARAMETER(p_info); // Is some situations BACKEND_IMPL_GET() macro may not use second parameter
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_free_impl, p_info->curve_type);
+
+ if (backend_implementation != NULL)
+ {
+ // Execute backend implementation
+ result = backend_implementation(p_public_key);
+ }
+ else
+ {
+ // Free is not implemented by the backend, so nothing have to deallocated.
+ result = NRF_SUCCESS;
+ }
+
+ // Clear init value to indicate invalid key
+ p_public_key_header->init_value = 0;
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_curve_info_get(
+ void const * p_key,
+ nrf_crypto_ecc_curve_info_t const ** pp_curve_info)
+{
+ ret_code_t result;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_key;
+
+ // Check and prepare parameters
+ VERIFY_TRUE(pp_curve_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ if (result != NRF_SUCCESS)
+ {
+ // p_key can be private or public key, so check second case here
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ }
+ VERIFY_SUCCESS(result);
+
+ // Write output parameter
+ *pp_curve_info = p_key_header->p_info;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_ecc_byte_order_invert(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ uint8_t const * p_raw_input,
+ uint8_t * p_raw_output,
+ size_t raw_data_size)
+{
+ uint8_t temp;
+ size_t from_index;
+ size_t to_index;
+ size_t integer_size;
+
+ if (p_curve_info == NULL)
+ {
+ integer_size = raw_data_size;
+ }
+ else
+ {
+ integer_size = p_curve_info->raw_private_key_size;
+ }
+
+ VERIFY_TRUE(p_raw_input != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_raw_output != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ // Loop over each big integer of the input
+ while (raw_data_size >= integer_size)
+ {
+ // Swap byte by byte in current integer
+ from_index = 0;
+ to_index = integer_size - 1;
+ while (from_index <= to_index)
+ {
+ // Swap bytes from source to destination, this may be the same buffer, so use temporary variable
+ temp = p_raw_input[from_index];
+ p_raw_output[from_index] = p_raw_input[to_index];
+ p_raw_output[to_index] = temp;
+ // Go to next pair of bytes
+ from_index++;
+ to_index--;
+ }
+ // Go to next integer
+ raw_data_size -= integer_size;
+ p_raw_input += integer_size;
+ p_raw_output += integer_size;
+ }
+
+ if (raw_data_size != 0)
+ {
+ // Input size is not a multiple of big integer size, so it is invalid
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_CRYPTO_ECC_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h
new file mode 100644
index 0000000..8fa825b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h
@@ -0,0 +1,999 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECC_H__
+#define NRF_CRYPTO_ECC_H__
+
+/** @addtogroup nrf_crypto
+ * @{
+ * @addtogroup nrf_crypto_ecc Elliptic Curve Cryptography Key Management
+ * @{
+ * @brief Provides elliptic curve cryptography API for public and private key management.
+ *
+ * @addtogroup nrf_crypto_ecc_secp160r1 Definitions specific to secp160r1 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecc_secp160r2 Definitions specific to secp160r2 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecc_secp192r1 Definitions specific to secp192r1 (NIST 192-bit)
+ * @addtogroup nrf_crypto_ecc_secp224r1 Definitions specific to secp224r1 (NIST 224-bit)
+ * @addtogroup nrf_crypto_ecc_secp256r1 Definitions specific to secp256r1 (NIST 256-bit)
+ * @addtogroup nrf_crypto_ecc_secp384r1 Definitions specific to secp384r1 (NIST 384-bit)
+ * @addtogroup nrf_crypto_ecc_secp521r1 Definitions specific to secp521r1 (NIST 521-bit)
+ * @addtogroup nrf_crypto_ecc_secp160k1 Definitions specific to secp160k1 (Koblitz 160-bit)
+ * @addtogroup nrf_crypto_ecc_secp192k1 Definitions specific to secp192k1 (Koblitz 192-bit)
+ * @addtogroup nrf_crypto_ecc_secp224k1 Definitions specific to secp224k1 (Koblitz 224-bit)
+ * @addtogroup nrf_crypto_ecc_secp256k1 Definitions specific to secp256k1 (Koblitz 256-bit)
+ * @addtogroup nrf_crypto_ecc_bp256r1 Definitions specific to bp256r1 (Brainpool 256-bit)
+ * @addtogroup nrf_crypto_ecc_bp384r1 Definitions specific to bp384r1 (Brainpool 384-bit)
+ * @addtogroup nrf_crypto_ecc_bp512r1 Definitions specific to bp512r1 (Brainpool 512-bit)
+ * @addtogroup nrf_crypto_ecc_curve25519 Definitions specific to Curve25519
+ * @addtogroup nrf_crypto_ecc_ed25519 Definitions specific to Ed25519
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecc_backend.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined(__SDK_DOXYGEN__)
+#define NRF_CRYPTO_ECC_SECP160R1_ENABLED 1 /**< @brief Defined as 1 if secp160r1 (NIST 160-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp160r1 */
+#define NRF_CRYPTO_ECC_SECP160R2_ENABLED 1 /**< @brief Defined as 1 if secp160r2 (NIST 160-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp160r2 */
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1 /**< @brief Defined as 1 if secp192r1 (NIST 192-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp192r1 */
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1 /**< @brief Defined as 1 if secp224r1 (NIST 224-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp224r1 */
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1 /**< @brief Defined as 1 if secp256r1 (NIST 256-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp256r1 */
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 1 /**< @brief Defined as 1 if secp384r1 (NIST 384-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp384r1 */
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 1 /**< @brief Defined as 1 if secp521r1 (NIST 521-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp521r1 */
+#define NRF_CRYPTO_ECC_SECP160K1_ENABLED 1 /**< @brief Defined as 1 if secp160k1 (Koblitz 160-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp160k1 */
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 1 /**< @brief Defined as 1 if secp192k1 (Koblitz 192-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp192k1 */
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 1 /**< @brief Defined as 1 if secp224k1 (Koblitz 224-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp224k1 */
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1 /**< @brief Defined as 1 if secp256k1 (Koblitz 256-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp256k1 */
+#define NRF_CRYPTO_ECC_BP256R1_ENABLED 1 /**< @brief Defined as 1 if bp256r1 (Brainpool 256-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_bp256r1 */
+#define NRF_CRYPTO_ECC_BP384R1_ENABLED 1 /**< @brief Defined as 1 if bp384r1 (Brainpool 384-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_bp384r1 */
+#define NRF_CRYPTO_ECC_BP512R1_ENABLED 1 /**< @brief Defined as 1 if bp512r1 (Brainpool 512-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_bp512r1 */
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 1 /**< @brief Defined as 1 if Curve25519 is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_curve25519 */
+#define NRF_CRYPTO_ECC_ED25519_ENABLED 1 /**< @brief Defined as 1 if Ed25519 is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_ed25519 */
+#endif
+
+
+#define NRF_CRYPTO_ECC_SECP160R1_RAW_PRIVATE_KEY_SIZE (160 / 8) /**< @brief Raw private key size for secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r1 */
+#define NRF_CRYPTO_ECC_SECP160R2_RAW_PRIVATE_KEY_SIZE (160 / 8) /**< @brief Raw private key size for secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r2 */
+#define NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE (192 / 8) /**< @brief Raw private key size for secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecc_secp192r1 */
+#define NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE (224 / 8) /**< @brief Raw private key size for secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecc_secp224r1 */
+#define NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecc_secp256r1 */
+#define NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE (384 / 8) /**< @brief Raw private key size for secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecc_secp384r1 */
+#define NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE (528 / 8) /**< @brief Raw private key size for secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecc_secp521r1 */
+#define NRF_CRYPTO_ECC_SECP160K1_RAW_PRIVATE_KEY_SIZE (160 / 8) /**< @brief Raw private key size for secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecc_secp160k1 */
+#define NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE (192 / 8) /**< @brief Raw private key size for secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecc_secp192k1 */
+#define NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE (224 / 8) /**< @brief Raw private key size for secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecc_secp224k1 */
+#define NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecc_secp256k1 */
+#define NRF_CRYPTO_ECC_BP256R1_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecc_bp256r1 */
+#define NRF_CRYPTO_ECC_BP384R1_RAW_PRIVATE_KEY_SIZE (384 / 8) /**< @brief Raw private key size for bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecc_bp384r1 */
+#define NRF_CRYPTO_ECC_BP512R1_RAW_PRIVATE_KEY_SIZE (512 / 8) /**< @brief Raw private key size for bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecc_bp512r1 */
+#define NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for Curve25519. @ingroup nrf_crypto_ecc_curve25519 */
+#define NRF_CRYPTO_ECC_ED25519_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for Ed25519. @ingroup nrf_crypto_ecc_ed25519 */
+
+
+#define NRF_CRYPTO_ECC_SECP160R1_RAW_PUBLIC_KEY_SIZE (2 * 160 / 8) /**< @brief Raw public key size for curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r1 */
+#define NRF_CRYPTO_ECC_SECP160R2_RAW_PUBLIC_KEY_SIZE (2 * 160 / 8) /**< @brief Raw public key size for curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r2 */
+#define NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE (2 * 192 / 8) /**< @brief Raw public key size for curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecc_secp192r1 */
+#define NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE (2 * 224 / 8) /**< @brief Raw public key size for curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecc_secp224r1 */
+#define NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE (2 * 256 / 8) /**< @brief Raw public key size for curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecc_secp256r1 */
+#define NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE (2 * 384 / 8) /**< @brief Raw public key size for curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecc_secp384r1 */
+#define NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE (2 * 528 / 8) /**< @brief Raw public key size for curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecc_secp521r1 */
+#define NRF_CRYPTO_ECC_SECP160K1_RAW_PUBLIC_KEY_SIZE (2 * 160 / 8) /**< @brief Raw public key size for curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecc_secp160k1 */
+#define NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE (2 * 192 / 8) /**< @brief Raw public key size for curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecc_secp192k1 */
+#define NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE (2 * 224 / 8) /**< @brief Raw public key size for curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecc_secp224k1 */
+#define NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE (2 * 256 / 8) /**< @brief Raw public key size for curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecc_secp256k1 */
+#define NRF_CRYPTO_ECC_BP256R1_RAW_PUBLIC_KEY_SIZE (2 * 256 / 8) /**< @brief Raw public key size for curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecc_bp256r1 */
+#define NRF_CRYPTO_ECC_BP384R1_RAW_PUBLIC_KEY_SIZE (2 * 384 / 8) /**< @brief Raw public key size for curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecc_bp384r1 */
+#define NRF_CRYPTO_ECC_BP512R1_RAW_PUBLIC_KEY_SIZE (2 * 512 / 8) /**< @brief Raw public key size for curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecc_bp512r1 */
+#define NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE (256 / 8) /**< @brief Raw public key size for curve Curve25519. @ingroup nrf_crypto_ecc_curve25519 */
+#define NRF_CRYPTO_ECC_ED25519_RAW_PUBLIC_KEY_SIZE (256 / 8) /**< @brief Raw public key size for curve Ed25519. @ingroup nrf_crypto_ecc_ed25519 */
+
+
+#define NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE /**< @brief Maximum size of a raw private key for all enabled curves. */
+#define NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE /**< @brief Maximum size of a raw public key for all enabled curves. */
+
+
+/** @brief Defines type of ECC curve.
+ */
+typedef enum
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_ECC_SECP160R1_CURVE_TYPE, /**< secp160r1 (NIST 160-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_ECC_SECP160R2_CURVE_TYPE, /**< secp160r2 (NIST 160-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE, /**< secp192r1 (NIST 192-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE, /**< secp224r1 (NIST 224-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE, /**< secp256r1 (NIST 256-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE, /**< secp384r1 (NIST 384-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE, /**< secp521r1 (NIST 521-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_ECC_SECP160K1_CURVE_TYPE, /**< secp160k1 (Koblitz 160-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE, /**< secp192k1 (Koblitz 192-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE, /**< secp224k1 (Koblitz 224-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE, /**< secp256k1 (Koblitz 256-bit) */
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_ECC_BP256R1_CURVE_TYPE, /**< bp256r1 (Brainpool 256-bit) */
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_ECC_BP384R1_CURVE_TYPE, /**< bp384r1 (Brainpool 384-bit) */
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_ECC_BP512R1_CURVE_TYPE, /**< bp512r1 (Brainpool 512-bit) */
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE, /**< Curve25519 */
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_ECC_ED25519_CURVE_TYPE, /**< Ed25519 */
+#endif
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_ECC_SECP160R1_CURVE_TYPE, /**< secp160r1 (NIST 160-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_ECC_SECP160R2_CURVE_TYPE, /**< secp160r2 (NIST 160-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE, /**< secp192r1 (NIST 192-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE, /**< secp224r1 (NIST 224-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE, /**< secp256r1 (NIST 256-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE, /**< secp384r1 (NIST 384-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE, /**< secp521r1 (NIST 521-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_ECC_SECP160K1_CURVE_TYPE, /**< secp160k1 (Koblitz 160-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE, /**< secp192k1 (Koblitz 192-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE, /**< secp224k1 (Koblitz 224-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE, /**< secp256k1 (Koblitz 256-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_ECC_BP256R1_CURVE_TYPE, /**< bp256r1 (Brainpool 256-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_ECC_BP384R1_CURVE_TYPE, /**< bp384r1 (Brainpool 384-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_ECC_BP512R1_CURVE_TYPE, /**< bp512r1 (Brainpool 512-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE, /**< Curve25519 */
+#endif
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_ECC_ED25519_CURVE_TYPE, /**< Ed25519 */
+#endif
+} nrf_crypto_ecc_curve_type_t;
+
+
+/** @brief Structure holding information on a specific curve.
+ *
+ * @note This structure cannot be used to create a new variable. Only the variables defined by this
+ * library can be used, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ */
+typedef struct nrf_crypto_ecc_curve_info_s
+{
+ uint16_t public_key_size; /**< @brief Size of a structure holding internal public key. */
+ uint16_t private_key_size; /**< @brief Size of a structure holding internal private key. */
+ nrf_crypto_ecc_curve_type_t curve_type; /**< @brief Type of the curve. */
+ uint8_t raw_private_key_size; /**< @brief Size of a buffer containing raw private key. */
+ uint8_t raw_public_key_size; /**< @brief Size of a buffer containing raw public key. */
+ void * p_backend_data; /**< @brief Field to hold backend specific internal data. */
+} nrf_crypto_ecc_curve_info_t;
+
+
+/** @addtogroup nrf_crypto_ecc_secp160r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp160r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp160r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp160r1 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp160r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp160r1 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r1_private_key_t
+ nrf_crypto_ecc_secp160r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp160r1 (NIST 160-bit) */
+typedef nrf_crypto_backend_secp160r1_public_key_t
+ nrf_crypto_ecc_secp160r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp160r1 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP160R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp160r1 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP160R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp160r1 (NIST 160-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+
+/** @brief Variable containing information on secp160r1 (NIST 160-bit).
+ *
+ * It can be used as a parameter for the functions creating secp160r1 (NIST 160-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp160r2
+ * @{ */
+
+typedef nrf_crypto_backend_secp160r2_key_pair_generate_context_t
+ nrf_crypto_ecc_secp160r2_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp160r2 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r2_public_key_calculate_context_t
+ nrf_crypto_ecc_secp160r2_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp160r2 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r2_private_key_t
+ nrf_crypto_ecc_secp160r2_private_key_t; /**< @brief Structure holding internal representation of a private key for secp160r2 (NIST 160-bit) */
+typedef nrf_crypto_backend_secp160r2_public_key_t
+ nrf_crypto_ecc_secp160r2_public_key_t; /**< @brief Structure holding internal representation of a public key for secp160r2 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r2_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP160R2_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp160r2 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r2_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP160R2_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp160r2 (NIST 160-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+
+/** @brief Variable containing information on secp160r2 (NIST 160-bit).
+ *
+ * It can be used as a parameter for the functions creating secp160r2 (NIST 160-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r2_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp192r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp192r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp192r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp192r1 (NIST 192-bit). */
+typedef nrf_crypto_backend_secp192r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp192r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp192r1 (NIST 192-bit). */
+typedef nrf_crypto_backend_secp192r1_private_key_t
+ nrf_crypto_ecc_secp192r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp192r1 (NIST 192-bit) */
+typedef nrf_crypto_backend_secp192r1_public_key_t
+ nrf_crypto_ecc_secp192r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp192r1 (NIST 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp192r1 (NIST 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp192r1 (NIST 192-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+
+/** @brief Variable containing information on secp192r1 (NIST 192-bit).
+ *
+ * It can be used as a parameter for the functions creating secp192r1 (NIST 192-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp224r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp224r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp224r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp224r1 (NIST 224-bit). */
+typedef nrf_crypto_backend_secp224r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp224r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp224r1 (NIST 224-bit). */
+typedef nrf_crypto_backend_secp224r1_private_key_t
+ nrf_crypto_ecc_secp224r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp224r1 (NIST 224-bit) */
+typedef nrf_crypto_backend_secp224r1_public_key_t
+ nrf_crypto_ecc_secp224r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp224r1 (NIST 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp224r1 (NIST 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp224r1 (NIST 224-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+
+/** @brief Variable containing information on secp224r1 (NIST 224-bit).
+ *
+ * It can be used as a parameter for the functions creating secp224r1 (NIST 224-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp256r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp256r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp256r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp256r1 (NIST 256-bit). */
+typedef nrf_crypto_backend_secp256r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp256r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp256r1 (NIST 256-bit). */
+typedef nrf_crypto_backend_secp256r1_private_key_t
+ nrf_crypto_ecc_secp256r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp256r1 (NIST 256-bit) */
+typedef nrf_crypto_backend_secp256r1_public_key_t
+ nrf_crypto_ecc_secp256r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp256r1 (NIST 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp256r1 (NIST 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp256r1 (NIST 256-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+
+/** @brief Variable containing information on secp256r1 (NIST 256-bit).
+ *
+ * It can be used as a parameter for the functions creating secp256r1 (NIST 256-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp384r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp384r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp384r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp384r1 (NIST 384-bit). */
+typedef nrf_crypto_backend_secp384r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp384r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp384r1 (NIST 384-bit). */
+typedef nrf_crypto_backend_secp384r1_private_key_t
+ nrf_crypto_ecc_secp384r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp384r1 (NIST 384-bit) */
+typedef nrf_crypto_backend_secp384r1_public_key_t
+ nrf_crypto_ecc_secp384r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp384r1 (NIST 384-bit) */
+typedef uint8_t nrf_crypto_ecc_secp384r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp384r1 (NIST 384-bit) */
+typedef uint8_t nrf_crypto_ecc_secp384r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp384r1 (NIST 384-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+
+/** @brief Variable containing information on secp384r1 (NIST 384-bit).
+ *
+ * It can be used as a parameter for the functions creating secp384r1 (NIST 384-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp384r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp521r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp521r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp521r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp521r1 (NIST 521-bit). */
+typedef nrf_crypto_backend_secp521r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp521r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp521r1 (NIST 521-bit). */
+typedef nrf_crypto_backend_secp521r1_private_key_t
+ nrf_crypto_ecc_secp521r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp521r1 (NIST 521-bit) */
+typedef nrf_crypto_backend_secp521r1_public_key_t
+ nrf_crypto_ecc_secp521r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp521r1 (NIST 521-bit) */
+typedef uint8_t nrf_crypto_ecc_secp521r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp521r1 (NIST 521-bit) */
+typedef uint8_t nrf_crypto_ecc_secp521r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp521r1 (NIST 521-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+
+/** @brief Variable containing information on secp521r1 (NIST 521-bit).
+ *
+ * It can be used as a parameter for the functions creating secp521r1 (NIST 521-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp521r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp160k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp160k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp160k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp160k1 (Koblitz 160-bit). */
+typedef nrf_crypto_backend_secp160k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp160k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp160k1 (Koblitz 160-bit). */
+typedef nrf_crypto_backend_secp160k1_private_key_t
+ nrf_crypto_ecc_secp160k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp160k1 (Koblitz 160-bit) */
+typedef nrf_crypto_backend_secp160k1_public_key_t
+ nrf_crypto_ecc_secp160k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp160k1 (Koblitz 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP160K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp160k1 (Koblitz 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP160K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp160k1 (Koblitz 160-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+
+/** @brief Variable containing information on secp160k1 (Koblitz 160-bit).
+ *
+ * It can be used as a parameter for the functions creating secp160k1 (Koblitz 160-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp192k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp192k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp192k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp192k1 (Koblitz 192-bit). */
+typedef nrf_crypto_backend_secp192k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp192k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp192k1 (Koblitz 192-bit). */
+typedef nrf_crypto_backend_secp192k1_private_key_t
+ nrf_crypto_ecc_secp192k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp192k1 (Koblitz 192-bit) */
+typedef nrf_crypto_backend_secp192k1_public_key_t
+ nrf_crypto_ecc_secp192k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp192k1 (Koblitz 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp192k1 (Koblitz 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp192k1 (Koblitz 192-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+
+/** @brief Variable containing information on secp192k1 (Koblitz 192-bit).
+ *
+ * It can be used as a parameter for the functions creating secp192k1 (Koblitz 192-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp224k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp224k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp224k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp224k1 (Koblitz 224-bit). */
+typedef nrf_crypto_backend_secp224k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp224k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp224k1 (Koblitz 224-bit). */
+typedef nrf_crypto_backend_secp224k1_private_key_t
+ nrf_crypto_ecc_secp224k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp224k1 (Koblitz 224-bit) */
+typedef nrf_crypto_backend_secp224k1_public_key_t
+ nrf_crypto_ecc_secp224k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp224k1 (Koblitz 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp224k1 (Koblitz 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp224k1 (Koblitz 224-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+
+/** @brief Variable containing information on secp224k1 (Koblitz 224-bit).
+ *
+ * It can be used as a parameter for the functions creating secp224k1 (Koblitz 224-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp256k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp256k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp256k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp256k1 (Koblitz 256-bit). */
+typedef nrf_crypto_backend_secp256k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp256k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp256k1 (Koblitz 256-bit). */
+typedef nrf_crypto_backend_secp256k1_private_key_t
+ nrf_crypto_ecc_secp256k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp256k1 (Koblitz 256-bit) */
+typedef nrf_crypto_backend_secp256k1_public_key_t
+ nrf_crypto_ecc_secp256k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp256k1 (Koblitz 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp256k1 (Koblitz 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp256k1 (Koblitz 256-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+
+/** @brief Variable containing information on secp256k1 (Koblitz 256-bit).
+ *
+ * It can be used as a parameter for the functions creating secp256k1 (Koblitz 256-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_bp256r1
+ * @{ */
+
+typedef nrf_crypto_backend_bp256r1_key_pair_generate_context_t
+ nrf_crypto_ecc_bp256r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using bp256r1 (Brainpool 256-bit). */
+typedef nrf_crypto_backend_bp256r1_public_key_calculate_context_t
+ nrf_crypto_ecc_bp256r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using bp256r1 (Brainpool 256-bit). */
+typedef nrf_crypto_backend_bp256r1_private_key_t
+ nrf_crypto_ecc_bp256r1_private_key_t; /**< @brief Structure holding internal representation of a private key for bp256r1 (Brainpool 256-bit) */
+typedef nrf_crypto_backend_bp256r1_public_key_t
+ nrf_crypto_ecc_bp256r1_public_key_t; /**< @brief Structure holding internal representation of a public key for bp256r1 (Brainpool 256-bit) */
+typedef uint8_t nrf_crypto_ecc_bp256r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_BP256R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for bp256r1 (Brainpool 256-bit) */
+typedef uint8_t nrf_crypto_ecc_bp256r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_BP256R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for bp256r1 (Brainpool 256-bit) */
+
+
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+
+/** @brief Variable containing information on bp256r1 (Brainpool 256-bit).
+ *
+ * It can be used as a parameter for the functions creating bp256r1 (Brainpool 256-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp256r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_bp384r1
+ * @{ */
+
+typedef nrf_crypto_backend_bp384r1_key_pair_generate_context_t
+ nrf_crypto_ecc_bp384r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using bp384r1 (Brainpool 384-bit). */
+typedef nrf_crypto_backend_bp384r1_public_key_calculate_context_t
+ nrf_crypto_ecc_bp384r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using bp384r1 (Brainpool 384-bit). */
+typedef nrf_crypto_backend_bp384r1_private_key_t
+ nrf_crypto_ecc_bp384r1_private_key_t; /**< @brief Structure holding internal representation of a private key for bp384r1 (Brainpool 384-bit) */
+typedef nrf_crypto_backend_bp384r1_public_key_t
+ nrf_crypto_ecc_bp384r1_public_key_t; /**< @brief Structure holding internal representation of a public key for bp384r1 (Brainpool 384-bit) */
+typedef uint8_t nrf_crypto_ecc_bp384r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_BP384R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for bp384r1 (Brainpool 384-bit) */
+typedef uint8_t nrf_crypto_ecc_bp384r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_BP384R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for bp384r1 (Brainpool 384-bit) */
+
+
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+
+/** @brief Variable containing information on bp384r1 (Brainpool 384-bit).
+ *
+ * It can be used as a parameter for the functions creating bp384r1 (Brainpool 384-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp384r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_bp512r1
+ * @{ */
+
+typedef nrf_crypto_backend_bp512r1_key_pair_generate_context_t
+ nrf_crypto_ecc_bp512r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using bp512r1 (Brainpool 512-bit). */
+typedef nrf_crypto_backend_bp512r1_public_key_calculate_context_t
+ nrf_crypto_ecc_bp512r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using bp512r1 (Brainpool 512-bit). */
+typedef nrf_crypto_backend_bp512r1_private_key_t
+ nrf_crypto_ecc_bp512r1_private_key_t; /**< @brief Structure holding internal representation of a private key for bp512r1 (Brainpool 512-bit) */
+typedef nrf_crypto_backend_bp512r1_public_key_t
+ nrf_crypto_ecc_bp512r1_public_key_t; /**< @brief Structure holding internal representation of a public key for bp512r1 (Brainpool 512-bit) */
+typedef uint8_t nrf_crypto_ecc_bp512r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_BP512R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for bp512r1 (Brainpool 512-bit) */
+typedef uint8_t nrf_crypto_ecc_bp512r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_BP512R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for bp512r1 (Brainpool 512-bit) */
+
+
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+
+/** @brief Variable containing information on bp512r1 (Brainpool 512-bit).
+ *
+ * It can be used as a parameter for the functions creating bp512r1 (Brainpool 512-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp512r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_curve25519
+ * @{ */
+
+typedef nrf_crypto_backend_curve25519_key_pair_generate_context_t
+ nrf_crypto_ecc_curve25519_key_pair_generate_context_t; /**< @brief Context structure for key generation using Curve25519. */
+typedef nrf_crypto_backend_curve25519_public_key_calculate_context_t
+ nrf_crypto_ecc_curve25519_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using Curve25519. */
+typedef nrf_crypto_backend_curve25519_private_key_t
+ nrf_crypto_ecc_curve25519_private_key_t; /**< @brief Structure holding internal representation of a private key for Curve25519 */
+typedef nrf_crypto_backend_curve25519_public_key_t
+ nrf_crypto_ecc_curve25519_public_key_t; /**< @brief Structure holding internal representation of a public key for Curve25519 */
+typedef uint8_t nrf_crypto_ecc_curve25519_raw_private_key_t
+ [NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for Curve25519 */
+typedef uint8_t nrf_crypto_ecc_curve25519_raw_public_key_t
+ [NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for Curve25519 */
+
+
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+
+/** @brief Variable containing information on Curve25519.
+ *
+ * It can be used as a parameter for the functions creating Curve25519 keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_curve25519_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_ed25519
+ * @{ */
+
+typedef nrf_crypto_backend_ed25519_key_pair_generate_context_t
+ nrf_crypto_ecc_ed25519_key_pair_generate_context_t; /**< @brief Context structure for key generation using Ed25519. */
+typedef nrf_crypto_backend_ed25519_public_key_calculate_context_t
+ nrf_crypto_ecc_ed25519_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using Ed25519. */
+typedef nrf_crypto_backend_ed25519_private_key_t
+ nrf_crypto_ecc_ed25519_private_key_t; /**< @brief Structure holding internal representation of a private key for Ed25519 */
+typedef nrf_crypto_backend_ed25519_public_key_t
+ nrf_crypto_ecc_ed25519_public_key_t; /**< @brief Structure holding internal representation of a public key for Ed25519 */
+typedef uint8_t nrf_crypto_ecc_ed25519_raw_private_key_t
+ [NRF_CRYPTO_ECC_ED25519_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for Ed25519 */
+typedef uint8_t nrf_crypto_ecc_ed25519_raw_public_key_t
+ [NRF_CRYPTO_ECC_ED25519_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for Ed25519 */
+
+
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+
+/** @brief Variable containing information on Ed25519.
+ *
+ * It can be used as a parameter for the functions creating Ed25519 keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_ed25519_curve_info;
+
+#endif
+
+/** @} */
+
+
+typedef uint8_t nrf_crypto_ecc_raw_private_key_t[NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE]; /**< @brief Type big enough to hold a raw private key for any the enabled curves. */
+typedef uint8_t nrf_crypto_ecc_raw_public_key_t [NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE]; /**< @brief Type big enough to hold a raw public key for any the enabled curves. */
+
+
+/** @brief Union holding a context for a key pair generation.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_key_pair_generate_context_t context_secp160r1; /**< @brief Holds context for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_key_pair_generate_context_t context_secp160r2; /**< @brief Holds context for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_key_pair_generate_context_t context_secp192r1; /**< @brief Holds context for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_key_pair_generate_context_t context_secp224r1; /**< @brief Holds context for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_key_pair_generate_context_t context_secp256r1; /**< @brief Holds context for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_key_pair_generate_context_t context_secp384r1; /**< @brief Holds context for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_key_pair_generate_context_t context_secp521r1; /**< @brief Holds context for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_key_pair_generate_context_t context_secp160k1; /**< @brief Holds context for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_key_pair_generate_context_t context_secp192k1; /**< @brief Holds context for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_key_pair_generate_context_t context_secp224k1; /**< @brief Holds context for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_key_pair_generate_context_t context_secp256k1; /**< @brief Holds context for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_key_pair_generate_context_t context_bp256r1; /**< @brief Holds context for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_key_pair_generate_context_t context_bp384r1; /**< @brief Holds context for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_key_pair_generate_context_t context_bp512r1; /**< @brief Holds context for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_key_pair_generate_context_t context_curve25519; /**< @brief Holds context for Curve25519. */
+ nrf_crypto_ecc_ed25519_key_pair_generate_context_t context_ed25519; /**< @brief Holds context for Ed25519. */
+} nrf_crypto_ecc_key_pair_generate_context_t;
+
+
+/** @brief Union holding a context for a public key calculation.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_public_key_calculate_context_t context_secp160r1; /**< @brief Holds context for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_public_key_calculate_context_t context_secp160r2; /**< @brief Holds context for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_public_key_calculate_context_t context_secp192r1; /**< @brief Holds context for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_public_key_calculate_context_t context_secp224r1; /**< @brief Holds context for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_public_key_calculate_context_t context_secp256r1; /**< @brief Holds context for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_public_key_calculate_context_t context_secp384r1; /**< @brief Holds context for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_public_key_calculate_context_t context_secp521r1; /**< @brief Holds context for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_public_key_calculate_context_t context_secp160k1; /**< @brief Holds context for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_public_key_calculate_context_t context_secp192k1; /**< @brief Holds context for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_public_key_calculate_context_t context_secp224k1; /**< @brief Holds context for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_public_key_calculate_context_t context_secp256k1; /**< @brief Holds context for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_public_key_calculate_context_t context_bp256r1; /**< @brief Holds context for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_public_key_calculate_context_t context_bp384r1; /**< @brief Holds context for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_public_key_calculate_context_t context_bp512r1; /**< @brief Holds context for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_public_key_calculate_context_t context_curve25519; /**< @brief Holds context for Curve25519. */
+ nrf_crypto_ecc_ed25519_public_key_calculate_context_t context_ed25519; /**< @brief Holds context for Ed25519. */
+} nrf_crypto_ecc_public_key_calculate_context_t;
+
+
+/** @brief Union holding representation of a private key for any curve type.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_private_key_t key_secp160r1; /**< @brief Holds internal representation of a private key for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_private_key_t key_secp160r2; /**< @brief Holds internal representation of a private key for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_private_key_t key_secp192r1; /**< @brief Holds internal representation of a private key for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_private_key_t key_secp224r1; /**< @brief Holds internal representation of a private key for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_private_key_t key_secp256r1; /**< @brief Holds internal representation of a private key for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_private_key_t key_secp384r1; /**< @brief Holds internal representation of a private key for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_private_key_t key_secp521r1; /**< @brief Holds internal representation of a private key for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_private_key_t key_secp160k1; /**< @brief Holds internal representation of a private key for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_private_key_t key_secp192k1; /**< @brief Holds internal representation of a private key for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_private_key_t key_secp224k1; /**< @brief Holds internal representation of a private key for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_private_key_t key_secp256k1; /**< @brief Holds internal representation of a private key for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_private_key_t key_bp256r1; /**< @brief Holds internal representation of a private key for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_private_key_t key_bp384r1; /**< @brief Holds internal representation of a private key for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_private_key_t key_bp512r1; /**< @brief Holds internal representation of a private key for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_private_key_t key_curve25519; /**< @brief Holds internal representation of a private key for Curve25519. */
+ nrf_crypto_ecc_ed25519_private_key_t key_ed25519; /**< @brief Holds internal representation of a private key for Ed25519. */
+} nrf_crypto_ecc_private_key_t;
+
+
+/** @brief Union holding representation of a public key for any curve type.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_public_key_t key_secp160r1; /**< @brief Holds internal representation of a public key for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_public_key_t key_secp160r2; /**< @brief Holds internal representation of a public key for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_public_key_t key_secp192r1; /**< @brief Holds internal representation of a public key for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_public_key_t key_secp224r1; /**< @brief Holds internal representation of a public key for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_public_key_t key_secp256r1; /**< @brief Holds internal representation of a public key for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_public_key_t key_secp384r1; /**< @brief Holds internal representation of a public key for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_public_key_t key_secp521r1; /**< @brief Holds internal representation of a public key for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_public_key_t key_secp160k1; /**< @brief Holds internal representation of a public key for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_public_key_t key_secp192k1; /**< @brief Holds internal representation of a public key for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_public_key_t key_secp224k1; /**< @brief Holds internal representation of a public key for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_public_key_t key_secp256k1; /**< @brief Holds internal representation of a public key for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_public_key_t key_bp256r1; /**< @brief Holds internal representation of a public key for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_public_key_t key_bp384r1; /**< @brief Holds internal representation of a public key for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_public_key_t key_bp512r1; /**< @brief Holds internal representation of a public key for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_public_key_t key_curve25519; /**< @brief Holds internal representation of a public key for Curve25519. */
+ nrf_crypto_ecc_ed25519_public_key_t key_ed25519; /**< @brief Holds internal representation of a public key for Ed25519. */
+} nrf_crypto_ecc_public_key_t;
+
+
+/** @brief Generate a new pair of a public key and a private key.
+ *
+ * Generated keys have to deallocated using @ref nrf_crypto_ecc_private_key_free and
+ * @ref nrf_crypto_ecc_public_key_free.
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[out] p_private_key Pointer to structure where newly generated private key will be put.
+ * @param[out] p_public_key Pointer to structure where newly generated public key will be put.
+ */
+ret_code_t nrf_crypto_ecc_key_pair_generate(
+ nrf_crypto_ecc_key_pair_generate_context_t * p_context,
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key);
+
+
+/** @brief Calculate public key associated with provided private key.
+ *
+ * Calculated public key has to be deallocated using @ref nrf_crypto_ecc_public_key_free.
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_private_key Pointer to structure holding a private key that will be used for computation.
+ * @param[out] p_public_key Pointer to structure where newly generated public key will be put.
+ */
+ret_code_t nrf_crypto_ecc_public_key_calculate(
+ nrf_crypto_ecc_public_key_calculate_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key);
+
+
+/** @brief Create a private key from a raw data.
+ *
+ * Generated private key has to be deallocated using @ref nrf_crypto_ecc_private_key_free.
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[out] p_private_key Pointer to structure where newly converted private key will be put.
+ * @param[in] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in] raw_data_size Number of bytes of a raw data. Correct size for selected curve can be found in
+ * @p p_curve_info and it is also defined by the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_private_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size);
+
+
+/** @brief Convert a private key to a raw data.
+ *
+ * @param[in] p_private_key Pointer to structure holding private key that will be convert.
+ * @param[out] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in,out] p_raw_data_size Maximum number of bytes that @p p_raw_data buffer can hold on input
+ * and the actual number of bytes used by the raw data on output.
+ * Actual size for selected curve can be found in
+ * @ref nrf_crypto_ecc_curve_info_t and it is also defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_private_key_to_raw(
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size);
+
+
+/** @brief Create a public key from a raw data.
+ *
+ * Generated public key has to be deallocated using @ref nrf_crypto_ecc_public_key_free.
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[out] p_public_key Pointer to structure where newly converted public key will be put.
+ * @param[in] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in] raw_data_size Number of bytes of a raw data. Correct size for selected curve can be found in
+ * @p p_curve_info and it is also defined by the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_public_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_public_key_t * p_public_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size);
+
+
+/** @brief Convert a public key to a raw data.
+ *
+ * @param[in] p_public_key Pointer to structure holding public key that will be convert.
+ * @param[out] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in,out] p_raw_data_size Maximum number of bytes that @p p_raw_data buffer can hold on input
+ * and the actual number of bytes used by the raw data on output.
+ * Actual size for selected curve can be found in
+ * @ref nrf_crypto_ecc_curve_info_t and it is also defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_public_key_to_raw(
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size);
+
+
+/** @brief Release resources taken by a private key.
+ *
+ * @param[in] p_private_key Pointer to structure holding private key to release.
+ */
+ret_code_t nrf_crypto_ecc_private_key_free(
+ nrf_crypto_ecc_private_key_t * p_private_key);
+
+
+/** @brief Release resources taken by a public key.
+ *
+ * @param[in] p_public_key Pointer to structure holding public key to release.
+ */
+ret_code_t nrf_crypto_ecc_public_key_free(
+ nrf_crypto_ecc_public_key_t * p_public_key);
+
+
+/** @brief Gets curve information structure from provided key (private or public).
+ *
+ * @param[in] p_key Pointer to structure holding private or public key.
+ * @param[out] pp_curve_info Pointer to location where put retrieved pointer to curve information structure.
+ */
+ret_code_t nrf_crypto_ecc_curve_info_get(
+ void const * p_key,
+ nrf_crypto_ecc_curve_info_t const ** pp_curve_info);
+
+
+/** @brief Inverts byte order of a big integers contained in a raw data.
+ *
+ * All the ECC API accepts only data with big endian integers, so this function have to be used
+ * if little endian is required. If input is in little endian byte order it will be converted
+ * to big endian. If input is in big endian byte order it will be converted to little endian.
+ * It works for ECC raw private key, raw public key, signature and shared secret. If raw data
+ * contains two big integers (e.g. R, S, or X, Y) each integer is inverted separately.
+ * If @p p_curve_info is NULL then all bytes in buffer will be inverted regardless what is the
+ * content of the buffer.
+ *
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[in] p_raw_input Pointer to buffer holding source data.
+ * @param[out] p_raw_output Pointer to buffer that will be filled with inverted byte order.
+ * This parameter can be the same as @p p_raw_input, otherwise the
+ * buffers cannot overlap.
+ * @param[in] raw_data_size Size of input and output buffer.
+ */
+ret_code_t nrf_crypto_ecc_byte_order_invert(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ uint8_t const * p_raw_input,
+ uint8_t * p_raw_output,
+ size_t raw_data_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}
+ * @}
+ */
+
+#endif // NRF_CRYPTO_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h
new file mode 100644
index 0000000..7ec1563
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECC_BACKEND_H__
+#define NRF_CRYPTO_ECC_BACKEND_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc_shared.h"
+
+// Include all backends
+#include "cc310_backend_ecc.h"
+#include "cc310_bl_backend_ecc.h"
+#include "mbedtls_backend_ecc.h"
+#include "oberon_backend_ecc.h"
+#include "micro_ecc_backend_ecc.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// Make sure that all required defines are defined
+#if !defined(NRF_CRYPTO_ECC_SECP160R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP160R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP160R2_ENABLED)
+#define NRF_CRYPTO_ECC_SECP160R2_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP192R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP224R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP256R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP384R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP521R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP160K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP160K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP192K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP224K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP256K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_BP256R1_ENABLED)
+#define NRF_CRYPTO_ECC_BP256R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_BP384R1_ENABLED)
+#define NRF_CRYPTO_ECC_BP384R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_BP512R1_ENABLED)
+#define NRF_CRYPTO_ECC_BP512R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_CURVE25519_ENABLED)
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_ED25519_ENABLED)
+#define NRF_CRYPTO_ECC_ED25519_ENABLED 0
+#endif
+
+
+/** @internal @brief Definition to detect if ECC submodule is enabled. It will be enabled if any
+ * curve of any of the backends is enabled.
+ */
+#define NRF_CRYPTO_ECC_ENABLED ( \
+ NRF_MODULE_ENABLED(NRF_CRYPTO) && ( \
+ NRF_CRYPTO_ECC_SECP160R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP160R2_ENABLED | \
+ NRF_CRYPTO_ECC_SECP192R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP224R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP256R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP384R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP521R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP160K1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP192K1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP224K1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP256K1_ENABLED | \
+ NRF_CRYPTO_ECC_BP256R1_ENABLED | \
+ NRF_CRYPTO_ECC_BP384R1_ENABLED | \
+ NRF_CRYPTO_ECC_BP512R1_ENABLED | \
+ NRF_CRYPTO_ECC_CURVE25519_ENABLED | \
+ NRF_CRYPTO_ECC_ED25519_ENABLED))
+
+
+/** @internal @brief Definition containing number of enabled curves.
+ */
+#define NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT ( \
+ NRF_CRYPTO_ECC_SECP160R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP160R2_ENABLED + \
+ NRF_CRYPTO_ECC_SECP192R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP224R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP256R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP384R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP521R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP160K1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP192K1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP224K1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP256K1_ENABLED + \
+ NRF_CRYPTO_ECC_BP256R1_ENABLED + \
+ NRF_CRYPTO_ECC_BP384R1_ENABLED + \
+ NRF_CRYPTO_ECC_BP512R1_ENABLED + \
+ NRF_CRYPTO_ECC_CURVE25519_ENABLED + \
+ NRF_CRYPTO_ECC_ED25519_ENABLED)
+
+
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp160r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp160r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp160r2_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp160r2_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r2_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r2_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp384r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp384r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp384r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp521r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp521r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp521r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp521r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp160k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp160k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp192k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp224k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_bp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp256r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp256r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp256r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_bp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp384r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp384r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp384r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_bp512r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp512r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp512r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp512r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_curve25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_curve25519_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_curve25519_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_ed25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_ed25519_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_ed25519_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_ed25519_public_key_t;
+#endif
+
+
+// Find biggest raw private and public key size that is currently enabled
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (66)
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (64)
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED || NRF_CRYPTO_ECC_SECP384R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (48)
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED || NRF_CRYPTO_ECC_SECP256K1_ENABLED || NRF_CRYPTO_ECC_CURVE25519_ENABLED || NRF_CRYPTO_ECC_ED25519_ENABLED || NRF_CRYPTO_ECC_SECP256R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (32)
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED || NRF_CRYPTO_ECC_SECP224R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (28)
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED || NRF_CRYPTO_ECC_SECP192R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (24)
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED || NRF_CRYPTO_ECC_SECP160R1_ENABLED || NRF_CRYPTO_ECC_SECP160R2_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (20)
+#else
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (1)
+#endif
+
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 66)
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 64)
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED || NRF_CRYPTO_ECC_SECP384R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 48)
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED || NRF_CRYPTO_ECC_SECP256K1_ENABLED || NRF_CRYPTO_ECC_SECP256R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 32)
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED || NRF_CRYPTO_ECC_SECP224R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 28)
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED || NRF_CRYPTO_ECC_SECP192R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 24)
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED || NRF_CRYPTO_ECC_SECP160R1_ENABLED || NRF_CRYPTO_ECC_SECP160R2_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 20)
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED || NRF_CRYPTO_ECC_ED25519_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (32)
+#else
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (1)
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECC_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h
new file mode 100644
index 0000000..33fd37f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h
@@ -0,0 +1,229 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECC_SHARED_H__
+#define NRF_CRYPTO_ECC_SHARED_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "sdk_errors.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE (0x4D465276) /**< @internal @brief Init value for all ECC private keys. ASCII "nRFv". */
+#define NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE (0x4D465270) /**< @internal @brief Init value for all ECC public keys. ASCII "nRFp". */
+
+
+// Forward declaration only
+struct nrf_crypto_ecc_curve_info_s;
+
+
+/** @brief Header structure at the beginning of each key structure.
+ */
+typedef struct
+{
+ uint32_t init_value; /**< @internal @brief Init value to check if key was correctly initialized. */
+ struct nrf_crypto_ecc_curve_info_s const * p_info; /**< @internal @brief Points to information structure of an associated curve type. */
+} nrf_crypto_internal_ecc_key_header_t;
+
+
+/** @internal @brief Function pointer for backend implementation of a key pair garatarion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[out] p_private_key Pointer where to put new private key.
+ * @param[out] p_public_key Pointer where to put new public key.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_key_pair_generate_fn_t)(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal @brief Function pointer for backend implementation of a public key calculation.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_private_key Pointer to private key.
+ * @param[out] p_public_key Pointer where to put new public key.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_public_key_calculate_fn_t)(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+/** @internal @brief Function pointer for backend implementation of raw to private key conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[out] p_private_key Pointer where to put new private key.
+ * @param[in] p_raw_data Pointer to raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_private_key_from_raw_fn_t)(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of private key to raw conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_private_key Pointer to private key.
+ * @param[out] p_raw_data Pointer where to put raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_private_key_to_raw_fn_t)(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of raw to public key conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[out] p_public_key Pointer where to put new public key.
+ * @param[in] p_raw_data Pointer to raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_public_key_from_raw_fn_t)(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of public key to raw conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_public_key Pointer to public key.
+ * @param[out] p_raw_data Pointer where to put raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_public_key_to_raw_fn_t)(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of key (public or private) deallocation.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_key Pointer to public or private key.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_key_free_fn_t)(
+ void * p_key);
+
+
+/** @internal @brief Function for checking and preparing ECC key output parameter.
+ *
+ * @param[in] p_curve_info Curve info provided by user that will be used to create a new key.
+ * @param[out] p_key_header Key header that have to be prepared.
+ * @return NRF_SUCCESS if parameters are valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_key_output_prepare(
+ struct nrf_crypto_ecc_curve_info_s const * p_curve_info,
+ nrf_crypto_internal_ecc_key_header_t * p_key_header);
+
+
+/** @internal @brief Function for checking ECC key input parameter.
+ *
+ * @param[in] p_key_header Key header that have to be checked.
+ * @param[in] init_value Expected init value in this key.
+ * @return NRF_SUCCESS if parameter is valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_key_input_check(
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header,
+ uint32_t init_value);
+
+
+/** @internal @brief Function for checking and preparing raw data output parameter.
+ *
+ * @param[out] p_raw_data Buffer where output will be written.
+ * @param[in,out] p_raw_data_size Pointer to size of the data. On input this is size of provided by
+ * the user buffer. On output is equal @p expected_size. This pointer
+ * can be NULL if used does not want to do size checking.
+ * @param[in] expected_size Size of output data that will be written to the buffer.
+ * @return NRF_SUCCESS if parameters are valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_raw_output_prepare(
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size,
+ size_t expected_size);
+
+
+/** @internal @brief Function for checking raw data input parameter.
+ *
+ * @param[in] p_raw_data Buffer where data is located.
+ * @param[in] raw_data_size Size of the data.Function will fail if it is different than @p expected_size.
+ * @param[in] expected_size Expected size of the data.
+ * @return NRF_SUCCESS if parameters are valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_raw_input_check(
+ uint8_t const * p_raw_data,
+ size_t raw_data_size,
+ size_t expected_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECC_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c
new file mode 100644
index 0000000..3d7d798
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+
+#if NRF_CRYPTO_ECC_ENABLED
+
+
+#if NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT > 1
+
+
+static const nrf_crypto_backend_ecdh_compute_fn_t compute_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_ecdh_compute,
+#endif
+};
+
+
+static const uint16_t compute_impl_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_ECDH_CONTEXT_SIZE,
+#endif
+};
+
+#define BACKEND_IMPL_GET(table, curve_type) (table)[(uint32_t)(curve_type)]
+
+#else
+
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp160r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP160R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160R2_ENABLED
+#define compute_impl nrf_crypto_backend_secp160r2_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP160R2_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp192r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp224r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp256r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP384R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp384r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP521R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp521r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp160k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP160K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp192k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp224k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp256k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED
+#define compute_impl nrf_crypto_backend_bp256r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_BP256R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED
+#define compute_impl nrf_crypto_backend_bp384r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_BP384R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+#define compute_impl nrf_crypto_backend_bp512r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_BP512R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED
+#define compute_impl nrf_crypto_backend_curve25519_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_ED25519_ENABLED
+#define compute_impl nrf_crypto_backend_ed25519_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_ED25519_ECDH_CONTEXT_SIZE
+#else
+#define compute_impl NULL
+#define compute_impl_context_size 0
+#endif
+
+#define BACKEND_IMPL_GET(function, curve_type) (function)
+
+#endif
+
+
+ret_code_t nrf_crypto_ecdh_compute(
+ nrf_crypto_ecdh_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_shared_secret,
+ size_t * p_shared_secret_size)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecdh_compute_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header for each key
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+ nrf_crypto_internal_ecc_key_header_t const * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ VERIFY_TRUE(p_private_key_header->p_info == p_public_key_header->p_info,
+ NRF_ERROR_CRYPTO_ECDH_CURVE_MISMATCH);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(
+ p_shared_secret,
+ p_shared_secret_size,
+ p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(compute_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(compute_impl_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_public_key, p_shared_secret);
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+#endif // NRF_CRYPTO_ECC_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h
new file mode 100644
index 0000000..7b177ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDH_H__
+#define NRF_CRYPTO_ECDH_H__
+
+/** @addtogroup nrf_crypto
+ * @{
+ * @addtogroup nrf_crypto_ecdh Elliptic Curve Diffie-Hellman (ECDH)
+ * @{
+ * @brief Provides elliptic curve cryptography functions for Diffie-Hellman shared secret exchange.
+ *
+ * @addtogroup nrf_crypto_ecdh_secp160r1 Definitions specific to secp160r1 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdh_secp160r2 Definitions specific to secp160r2 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdh_secp192r1 Definitions specific to secp192r1 (NIST 192-bit)
+ * @addtogroup nrf_crypto_ecdh_secp224r1 Definitions specific to secp224r1 (NIST 224-bit)
+ * @addtogroup nrf_crypto_ecdh_secp256r1 Definitions specific to secp256r1 (NIST 256-bit)
+ * @addtogroup nrf_crypto_ecdh_secp384r1 Definitions specific to secp384r1 (NIST 384-bit)
+ * @addtogroup nrf_crypto_ecdh_secp521r1 Definitions specific to secp521r1 (NIST 521-bit)
+ * @addtogroup nrf_crypto_ecdh_secp160k1 Definitions specific to secp160k1 (Koblitz 160-bit)
+ * @addtogroup nrf_crypto_ecdh_secp192k1 Definitions specific to secp192k1 (Koblitz 192-bit)
+ * @addtogroup nrf_crypto_ecdh_secp224k1 Definitions specific to secp224k1 (Koblitz 224-bit)
+ * @addtogroup nrf_crypto_ecdh_secp256k1 Definitions specific to secp256k1 (Koblitz 256-bit)
+ * @addtogroup nrf_crypto_ecdh_bp256r1 Definitions specific to bp256r1 (Brainpool 256-bit)
+ * @addtogroup nrf_crypto_ecdh_bp384r1 Definitions specific to bp384r1 (Brainpool 384-bit)
+ * @addtogroup nrf_crypto_ecdh_bp512r1 Definitions specific to bp512r1 (Brainpool 512-bit)
+ * @addtogroup nrf_crypto_ecdh_curve25519 Definitions specific to Curve25519
+ * @addtogroup nrf_crypto_ecdh_ed25519 Definitions specific to Ed25519
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_CRYPTO_ECDH_SECP160R1_SHARED_SECRET_SIZE (160 / 8) /**< @brief Number of bytes in a shared secret using secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r1 */
+#define NRF_CRYPTO_ECDH_SECP160R2_SHARED_SECRET_SIZE (160 / 8) /**< @brief Number of bytes in a shared secret using secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r2 */
+#define NRF_CRYPTO_ECDH_SECP192R1_SHARED_SECRET_SIZE (192 / 8) /**< @brief Number of bytes in a shared secret using secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdh_secp192r1 */
+#define NRF_CRYPTO_ECDH_SECP224R1_SHARED_SECRET_SIZE (224 / 8) /**< @brief Number of bytes in a shared secret using secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdh_secp224r1 */
+#define NRF_CRYPTO_ECDH_SECP256R1_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdh_secp256r1 */
+#define NRF_CRYPTO_ECDH_SECP384R1_SHARED_SECRET_SIZE (384 / 8) /**< @brief Number of bytes in a shared secret using secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdh_secp384r1 */
+#define NRF_CRYPTO_ECDH_SECP521R1_SHARED_SECRET_SIZE (528 / 8) /**< @brief Number of bytes in a shared secret using secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdh_secp521r1 */
+#define NRF_CRYPTO_ECDH_SECP160K1_SHARED_SECRET_SIZE (160 / 8) /**< @brief Number of bytes in a shared secret using secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdh_secp160k1 */
+#define NRF_CRYPTO_ECDH_SECP192K1_SHARED_SECRET_SIZE (192 / 8) /**< @brief Number of bytes in a shared secret using secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdh_secp192k1 */
+#define NRF_CRYPTO_ECDH_SECP224K1_SHARED_SECRET_SIZE (224 / 8) /**< @brief Number of bytes in a shared secret using secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdh_secp224k1 */
+#define NRF_CRYPTO_ECDH_SECP256K1_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdh_secp256k1 */
+#define NRF_CRYPTO_ECDH_BP256R1_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdh_bp256r1 */
+#define NRF_CRYPTO_ECDH_BP384R1_SHARED_SECRET_SIZE (384 / 8) /**< @brief Number of bytes in a shared secret using bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdh_bp384r1 */
+#define NRF_CRYPTO_ECDH_BP512R1_SHARED_SECRET_SIZE (512 / 8) /**< @brief Number of bytes in a shared secret using bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdh_bp512r1 */
+#define NRF_CRYPTO_ECDH_CURVE25519_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using Curve25519. @ingroup nrf_crypto_ecdh_curve25519 */
+#define NRF_CRYPTO_ECDH_ED25519_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using Ed25519. @ingroup nrf_crypto_ecdh_ed25519 */
+#define NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE /**< @brief Maximum size of a shared secret in bytes for all enabled curves. */
+
+
+typedef nrf_crypto_backend_secp160r1_ecdh_context_t nrf_crypto_ecdh_secp160r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r1 */
+typedef nrf_crypto_backend_secp160r2_ecdh_context_t nrf_crypto_ecdh_secp160r2_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r2 */
+typedef nrf_crypto_backend_secp192r1_ecdh_context_t nrf_crypto_ecdh_secp192r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdh_secp192r1 */
+typedef nrf_crypto_backend_secp224r1_ecdh_context_t nrf_crypto_ecdh_secp224r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdh_secp224r1 */
+typedef nrf_crypto_backend_secp256r1_ecdh_context_t nrf_crypto_ecdh_secp256r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdh_secp256r1 */
+typedef nrf_crypto_backend_secp384r1_ecdh_context_t nrf_crypto_ecdh_secp384r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdh_secp384r1 */
+typedef nrf_crypto_backend_secp521r1_ecdh_context_t nrf_crypto_ecdh_secp521r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdh_secp521r1 */
+typedef nrf_crypto_backend_secp160k1_ecdh_context_t nrf_crypto_ecdh_secp160k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdh_secp160k1 */
+typedef nrf_crypto_backend_secp192k1_ecdh_context_t nrf_crypto_ecdh_secp192k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdh_secp192k1 */
+typedef nrf_crypto_backend_secp224k1_ecdh_context_t nrf_crypto_ecdh_secp224k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdh_secp224k1 */
+typedef nrf_crypto_backend_secp256k1_ecdh_context_t nrf_crypto_ecdh_secp256k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdh_secp256k1 */
+typedef nrf_crypto_backend_bp256r1_ecdh_context_t nrf_crypto_ecdh_bp256r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdh_bp256r1 */
+typedef nrf_crypto_backend_bp384r1_ecdh_context_t nrf_crypto_ecdh_bp384r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdh_bp384r1 */
+typedef nrf_crypto_backend_bp512r1_ecdh_context_t nrf_crypto_ecdh_bp512r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdh_bp512r1 */
+typedef nrf_crypto_backend_curve25519_ecdh_context_t nrf_crypto_ecdh_curve25519_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve Curve25519. @ingroup nrf_crypto_ecdh_curve25519 */
+typedef nrf_crypto_backend_ed25519_ecdh_context_t nrf_crypto_ecdh_ed25519_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve Ed25519. @ingroup nrf_crypto_ecdh_ed25519 */
+
+
+typedef uint8_t nrf_crypto_ecdh_secp160r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP160R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r1 */
+typedef uint8_t nrf_crypto_ecdh_secp160r2_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP160R2_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r2 */
+typedef uint8_t nrf_crypto_ecdh_secp192r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP192R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdh_secp192r1 */
+typedef uint8_t nrf_crypto_ecdh_secp224r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP224R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdh_secp224r1 */
+typedef uint8_t nrf_crypto_ecdh_secp256r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP256R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdh_secp256r1 */
+typedef uint8_t nrf_crypto_ecdh_secp384r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP384R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdh_secp384r1 */
+typedef uint8_t nrf_crypto_ecdh_secp521r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP521R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdh_secp521r1 */
+typedef uint8_t nrf_crypto_ecdh_secp160k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP160K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdh_secp160k1 */
+typedef uint8_t nrf_crypto_ecdh_secp192k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP192K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdh_secp192k1 */
+typedef uint8_t nrf_crypto_ecdh_secp224k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP224K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdh_secp224k1 */
+typedef uint8_t nrf_crypto_ecdh_secp256k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP256K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdh_secp256k1 */
+typedef uint8_t nrf_crypto_ecdh_bp256r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_BP256R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdh_bp256r1 */
+typedef uint8_t nrf_crypto_ecdh_bp384r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_BP384R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdh_bp384r1 */
+typedef uint8_t nrf_crypto_ecdh_bp512r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_BP512R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdh_bp512r1 */
+typedef uint8_t nrf_crypto_ecdh_curve25519_shared_secret_t
+ [NRF_CRYPTO_ECDH_CURVE25519_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve Curve25519. @ingroup nrf_crypto_ecdh_curve25519 */
+typedef uint8_t nrf_crypto_ecdh_ed25519_shared_secret_t
+ [NRF_CRYPTO_ECDH_ED25519_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve Ed25519. @ingroup nrf_crypto_ecdh_ed25519 */
+typedef uint8_t nrf_crypto_ecdh_shared_secret_t
+ [NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE]; /**< @brief Array type of a shared secret for any of the enabled curves. */
+
+
+/** @brief Union holding a context for ECDH computation.
+ */
+typedef union
+{
+ nrf_crypto_ecdh_secp160r1_context_t context_secp160r1; /**< @brief Occupies space for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecdh_secp160r2_context_t context_secp160r2; /**< @brief Occupies space for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecdh_secp192r1_context_t context_secp192r1; /**< @brief Occupies space for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecdh_secp224r1_context_t context_secp224r1; /**< @brief Occupies space for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecdh_secp256r1_context_t context_secp256r1; /**< @brief Occupies space for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecdh_secp384r1_context_t context_secp384r1; /**< @brief Occupies space for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecdh_secp521r1_context_t context_secp521r1; /**< @brief Occupies space for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecdh_secp160k1_context_t context_secp160k1; /**< @brief Occupies space for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecdh_secp192k1_context_t context_secp192k1; /**< @brief Occupies space for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecdh_secp224k1_context_t context_secp224k1; /**< @brief Occupies space for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecdh_secp256k1_context_t context_secp256k1; /**< @brief Occupies space for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecdh_bp256r1_context_t context_bp256r1; /**< @brief Occupies space for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecdh_bp384r1_context_t context_bp384r1; /**< @brief Occupies space for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecdh_bp512r1_context_t context_bp512r1; /**< @brief Occupies space for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecdh_curve25519_context_t context_curve25519; /**< @brief Occupies space for Curve25519. */
+ nrf_crypto_ecdh_ed25519_context_t context_ed25519; /**< @brief Occupies space for Ed25519. */
+} nrf_crypto_ecdh_context_t;
+
+
+/** @brief Computes shared secret using ECC Diffie-Hellman.
+ *
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_private_key Pointer to structure holding a private key.
+ * @param[in] p_public_key Pointer to structure holding a public key received from the other party.
+ * @param[out] p_shared_secret Pointer to buffer where shared secret will be put.
+ * @param[in,out] p_shared_secret_size Maximum number of bytes that @p p_shared_secret buffer can hold on input
+ * and the actual number of bytes used by the data on output.
+ * Actual size for selected curve is defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECDH_SECP256R1_SHARED_SECRET_SIZE.
+ */
+ret_code_t nrf_crypto_ecdh_compute(
+ nrf_crypto_ecdh_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_shared_secret,
+ size_t * p_shared_secret_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}
+ * @}
+ */
+
+#endif // NRF_CRYPTO_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h
new file mode 100644
index 0000000..3b6f692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDH_BACKEND_H__
+#define NRF_CRYPTO_ECDH_BACKEND_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+// Include all backends
+#include "cc310_backend_ecdh.h"
+#include "cc310_bl_backend_ecdh.h"
+#include "mbedtls_backend_ecdh.h"
+#include "oberon_backend_ecdh.h"
+#include "micro_ecc_backend_ecdh.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp160r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp160r2_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r2_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp384r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp384r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp521r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp521r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp160k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp192k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp224k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_bp256r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp256r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_bp384r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp384r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_bp512r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp512r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_curve25519_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_curve25519_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_ed25519_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_ed25519_ecdh_compute NULL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECDH_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h
new file mode 100644
index 0000000..7d25cb1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDH_SHARED_H__
+#define NRF_CRYPTO_ECDH_SHARED_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_errors.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Function pointer for backend implementation of ECDH.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_private_key Pointer to private key.
+ * @param[in] p_public_key Pointer to public key.
+ * @param[out] p_shared_secret Pointer where to put generated shared secret.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecdh_compute_fn_t)(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECDH_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c
new file mode 100644
index 0000000..6258cb2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c
@@ -0,0 +1,471 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa.h"
+#include "nrf_crypto_mem.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+
+#if NRF_CRYPTO_ECC_ENABLED
+
+
+#if NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT > 1
+
+
+static const nrf_crypto_backend_ecdsa_sign_fn_t sign_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_sign,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_sign,
+#endif
+};
+
+static const uint16_t sign_impl_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE,
+#endif
+};
+
+static const nrf_crypto_backend_ecdsa_verify_fn_t verify_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_verify,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_verify,
+#endif
+};
+
+static const uint16_t verify_impl_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE,
+#endif
+};
+
+#define BACKEND_IMPL_GET(table, curve_type) (table)[(uint32_t)(curve_type)]
+
+#else
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp160r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp160r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160R2_ENABLED
+#define sign_impl nrf_crypto_backend_secp160r2_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp160r2_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp192r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp192r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp224r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp224r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp256r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp256r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP384R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp384r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp384r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP521R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp521r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp521r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp160k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp160k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp192k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp192k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp224k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp224k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp256k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp256k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED
+#define sign_impl nrf_crypto_backend_bp256r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_bp256r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED
+#define sign_impl nrf_crypto_backend_bp384r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_bp384r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+#define sign_impl nrf_crypto_backend_bp512r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_bp512r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED
+#define sign_impl nrf_crypto_backend_curve25519_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_curve25519_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_ED25519_ENABLED
+#define sign_impl nrf_crypto_backend_ed25519_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_ed25519_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE
+#else
+#define sign_impl NULL
+#define sign_impl_context_size 0
+#define verify_impl NULL
+#define verify_impl_context_size 0
+#endif
+
+#define BACKEND_IMPL_GET(function, curve_type) (function)
+
+#endif
+
+
+ret_code_t nrf_crypto_ecdsa_sign(
+ nrf_crypto_ecdsa_sign_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t * p_signature,
+ size_t * p_signature_size)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecdsa_sign_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+
+ // Check and prepare parameters
+ VERIFY_TRUE(p_hash != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(p_signature,
+ p_signature_size,
+ 2 * p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(sign_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(sign_impl_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_hash, hash_size, p_signature);
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecdsa_verify(
+ nrf_crypto_ecdsa_verify_context_t * p_context,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t const * p_signature,
+ size_t signature_size)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecdsa_verify_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_public_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_input_check(p_signature,
+ signature_size,
+ 2 * p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+ VERIFY_TRUE(p_hash != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(verify_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(verify_impl_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_public_key, p_hash, hash_size, p_signature);
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+#endif // NRF_CRYPTO_ECC_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h
new file mode 100644
index 0000000..a7726a5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h
@@ -0,0 +1,252 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDSA_H__
+#define NRF_CRYPTO_ECDSA_H__
+
+/** @addtogroup nrf_crypto
+ * @{
+ * @addtogroup nrf_crypto_ecdsa Elliptic Curve Digital Signature (ECDSA)
+ * @{
+ * @brief Provides elliptic curve cryptography functions for digital signature.
+ *
+ * @addtogroup nrf_crypto_ecdsa_secp160r1 Definitions specific to secp160r1 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp160r2 Definitions specific to secp160r2 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp192r1 Definitions specific to secp192r1 (NIST 192-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp224r1 Definitions specific to secp224r1 (NIST 224-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp256r1 Definitions specific to secp256r1 (NIST 256-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp384r1 Definitions specific to secp384r1 (NIST 384-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp521r1 Definitions specific to secp521r1 (NIST 521-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp160k1 Definitions specific to secp160k1 (Koblitz 160-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp192k1 Definitions specific to secp192k1 (Koblitz 192-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp224k1 Definitions specific to secp224k1 (Koblitz 224-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp256k1 Definitions specific to secp256k1 (Koblitz 256-bit)
+ * @addtogroup nrf_crypto_ecdsa_bp256r1 Definitions specific to bp256r1 (Brainpool 256-bit)
+ * @addtogroup nrf_crypto_ecdsa_bp384r1 Definitions specific to bp384r1 (Brainpool 384-bit)
+ * @addtogroup nrf_crypto_ecdsa_bp512r1 Definitions specific to bp512r1 (Brainpool 512-bit)
+ * @addtogroup nrf_crypto_ecdsa_curve25519 Definitions specific to Curve25519
+ * @addtogroup nrf_crypto_ecdsa_ed25519 Definitions specific to Ed25519
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#include "nrf_crypto_ecdsa_backend.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_ECDSA_SECP160R1_SIGNATURE_SIZE (2 * 160 / 8) /**< @brief Size of a signature for secp160r1 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r1 */
+#define NRF_CRYPTO_ECDSA_SECP160R2_SIGNATURE_SIZE (2 * 160 / 8) /**< @brief Size of a signature for secp160r2 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r2 */
+#define NRF_CRYPTO_ECDSA_SECP192R1_SIGNATURE_SIZE (2 * 192 / 8) /**< @brief Size of a signature for secp192r1 (NIST 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192r1 */
+#define NRF_CRYPTO_ECDSA_SECP224R1_SIGNATURE_SIZE (2 * 224 / 8) /**< @brief Size of a signature for secp224r1 (NIST 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224r1 */
+#define NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for secp256r1 (NIST 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256r1 */
+#define NRF_CRYPTO_ECDSA_SECP384R1_SIGNATURE_SIZE (2 * 384 / 8) /**< @brief Size of a signature for secp384r1 (NIST 384-bit) curve. @ingroup nrf_crypto_ecdsa_secp384r1 */
+#define NRF_CRYPTO_ECDSA_SECP521R1_SIGNATURE_SIZE (2 * 528 / 8) /**< @brief Size of a signature for secp521r1 (NIST 521-bit) curve. @ingroup nrf_crypto_ecdsa_secp521r1 */
+#define NRF_CRYPTO_ECDSA_SECP160K1_SIGNATURE_SIZE (2 * 160 / 8) /**< @brief Size of a signature for secp160k1 (Koblitz 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160k1 */
+#define NRF_CRYPTO_ECDSA_SECP192K1_SIGNATURE_SIZE (2 * 192 / 8) /**< @brief Size of a signature for secp192k1 (Koblitz 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192k1 */
+#define NRF_CRYPTO_ECDSA_SECP224K1_SIGNATURE_SIZE (2 * 224 / 8) /**< @brief Size of a signature for secp224k1 (Koblitz 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224k1 */
+#define NRF_CRYPTO_ECDSA_SECP256K1_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for secp256k1 (Koblitz 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256k1 */
+#define NRF_CRYPTO_ECDSA_BP256R1_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for bp256r1 (Brainpool 256-bit) curve. @ingroup nrf_crypto_ecdsa_bp256r1 */
+#define NRF_CRYPTO_ECDSA_BP384R1_SIGNATURE_SIZE (2 * 384 / 8) /**< @brief Size of a signature for bp384r1 (Brainpool 384-bit) curve. @ingroup nrf_crypto_ecdsa_bp384r1 */
+#define NRF_CRYPTO_ECDSA_BP512R1_SIGNATURE_SIZE (2 * 512 / 8) /**< @brief Size of a signature for bp512r1 (Brainpool 512-bit) curve. @ingroup nrf_crypto_ecdsa_bp512r1 */
+#define NRF_CRYPTO_ECDSA_CURVE25519_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for Curve25519 curve. @ingroup nrf_crypto_ecdsa_curve25519 */
+#define NRF_CRYPTO_ECDSA_ED25519_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for Ed25519 curve. @ingroup nrf_crypto_ecdsa_ed25519 */
+#define NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE (2 * NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE) /**< @brief Maximum size of a signature for all enabled curves. */
+
+
+typedef uint8_t nrf_crypto_ecdsa_secp160r1_signature_t [NRF_CRYPTO_ECDSA_SECP160R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp160r1 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp160r2_signature_t [NRF_CRYPTO_ECDSA_SECP160R2_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp160r2 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r2 */
+typedef uint8_t nrf_crypto_ecdsa_secp192r1_signature_t [NRF_CRYPTO_ECDSA_SECP192R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp192r1 (NIST 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp224r1_signature_t [NRF_CRYPTO_ECDSA_SECP224R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp224r1 (NIST 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp256r1_signature_t [NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp256r1 (NIST 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp384r1_signature_t [NRF_CRYPTO_ECDSA_SECP384R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp384r1 (NIST 384-bit) curve. @ingroup nrf_crypto_ecdsa_secp384r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp521r1_signature_t [NRF_CRYPTO_ECDSA_SECP521R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp521r1 (NIST 521-bit) curve. @ingroup nrf_crypto_ecdsa_secp521r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp160k1_signature_t [NRF_CRYPTO_ECDSA_SECP160K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp160k1 (Koblitz 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160k1 */
+typedef uint8_t nrf_crypto_ecdsa_secp192k1_signature_t [NRF_CRYPTO_ECDSA_SECP192K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp192k1 (Koblitz 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192k1 */
+typedef uint8_t nrf_crypto_ecdsa_secp224k1_signature_t [NRF_CRYPTO_ECDSA_SECP224K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp224k1 (Koblitz 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224k1 */
+typedef uint8_t nrf_crypto_ecdsa_secp256k1_signature_t [NRF_CRYPTO_ECDSA_SECP256K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp256k1 (Koblitz 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256k1 */
+typedef uint8_t nrf_crypto_ecdsa_bp256r1_signature_t [NRF_CRYPTO_ECDSA_BP256R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for bp256r1 (Brainpool 256-bit) curve. @ingroup nrf_crypto_ecdsa_bp256r1 */
+typedef uint8_t nrf_crypto_ecdsa_bp384r1_signature_t [NRF_CRYPTO_ECDSA_BP384R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for bp384r1 (Brainpool 384-bit) curve. @ingroup nrf_crypto_ecdsa_bp384r1 */
+typedef uint8_t nrf_crypto_ecdsa_bp512r1_signature_t [NRF_CRYPTO_ECDSA_BP512R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for bp512r1 (Brainpool 512-bit) curve. @ingroup nrf_crypto_ecdsa_bp512r1 */
+typedef uint8_t nrf_crypto_ecdsa_curve25519_signature_t [NRF_CRYPTO_ECDSA_CURVE25519_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for Curve25519 curve. @ingroup nrf_crypto_ecdsa_curve25519 */
+typedef uint8_t nrf_crypto_ecdsa_ed25519_signature_t [NRF_CRYPTO_ECDSA_ED25519_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for Ed25519 curve. @ingroup nrf_crypto_ecdsa_ed25519 */
+typedef uint8_t nrf_crypto_ecdsa_signature_t [NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE]; /**< @brief Type big enough to hold signature output for any curve type. */
+
+
+typedef nrf_crypto_backend_secp160r1_sign_context_t nrf_crypto_ecdsa_secp160r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r1 */
+typedef nrf_crypto_backend_secp160r2_sign_context_t nrf_crypto_ecdsa_secp160r2_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r2 */
+typedef nrf_crypto_backend_secp192r1_sign_context_t nrf_crypto_ecdsa_secp192r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdsa_secp192r1 */
+typedef nrf_crypto_backend_secp224r1_sign_context_t nrf_crypto_ecdsa_secp224r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdsa_secp224r1 */
+typedef nrf_crypto_backend_secp256r1_sign_context_t nrf_crypto_ecdsa_secp256r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdsa_secp256r1 */
+typedef nrf_crypto_backend_secp384r1_sign_context_t nrf_crypto_ecdsa_secp384r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdsa_secp384r1 */
+typedef nrf_crypto_backend_secp521r1_sign_context_t nrf_crypto_ecdsa_secp521r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdsa_secp521r1 */
+typedef nrf_crypto_backend_secp160k1_sign_context_t nrf_crypto_ecdsa_secp160k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdsa_secp160k1 */
+typedef nrf_crypto_backend_secp192k1_sign_context_t nrf_crypto_ecdsa_secp192k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdsa_secp192k1 */
+typedef nrf_crypto_backend_secp224k1_sign_context_t nrf_crypto_ecdsa_secp224k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdsa_secp224k1 */
+typedef nrf_crypto_backend_secp256k1_sign_context_t nrf_crypto_ecdsa_secp256k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdsa_secp256k1 */
+typedef nrf_crypto_backend_bp256r1_sign_context_t nrf_crypto_ecdsa_bp256r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdsa_bp256r1 */
+typedef nrf_crypto_backend_bp384r1_sign_context_t nrf_crypto_ecdsa_bp384r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdsa_bp384r1 */
+typedef nrf_crypto_backend_bp512r1_sign_context_t nrf_crypto_ecdsa_bp512r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdsa_bp512r1 */
+typedef nrf_crypto_backend_curve25519_sign_context_t nrf_crypto_ecdsa_curve25519_sign_context_t; /**< @brief Context used to store temporary data during signing with curve Curve25519. @ingroup nrf_crypto_ecdsa_curve25519 */
+typedef nrf_crypto_backend_ed25519_sign_context_t nrf_crypto_ecdsa_ed25519_sign_context_t; /**< @brief Context used to store temporary data during signing with curve Ed25519. @ingroup nrf_crypto_ecdsa_ed25519 */
+
+
+typedef nrf_crypto_backend_secp160r1_verify_context_t nrf_crypto_ecdsa_secp160r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r1 */
+typedef nrf_crypto_backend_secp160r2_verify_context_t nrf_crypto_ecdsa_secp160r2_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r2 */
+typedef nrf_crypto_backend_secp192r1_verify_context_t nrf_crypto_ecdsa_secp192r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdsa_secp192r1 */
+typedef nrf_crypto_backend_secp224r1_verify_context_t nrf_crypto_ecdsa_secp224r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdsa_secp224r1 */
+typedef nrf_crypto_backend_secp256r1_verify_context_t nrf_crypto_ecdsa_secp256r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdsa_secp256r1 */
+typedef nrf_crypto_backend_secp384r1_verify_context_t nrf_crypto_ecdsa_secp384r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdsa_secp384r1 */
+typedef nrf_crypto_backend_secp521r1_verify_context_t nrf_crypto_ecdsa_secp521r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdsa_secp521r1 */
+typedef nrf_crypto_backend_secp160k1_verify_context_t nrf_crypto_ecdsa_secp160k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdsa_secp160k1 */
+typedef nrf_crypto_backend_secp192k1_verify_context_t nrf_crypto_ecdsa_secp192k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdsa_secp192k1 */
+typedef nrf_crypto_backend_secp224k1_verify_context_t nrf_crypto_ecdsa_secp224k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdsa_secp224k1 */
+typedef nrf_crypto_backend_secp256k1_verify_context_t nrf_crypto_ecdsa_secp256k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdsa_secp256k1 */
+typedef nrf_crypto_backend_bp256r1_verify_context_t nrf_crypto_ecdsa_bp256r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdsa_bp256r1 */
+typedef nrf_crypto_backend_bp384r1_verify_context_t nrf_crypto_ecdsa_bp384r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdsa_bp384r1 */
+typedef nrf_crypto_backend_bp512r1_verify_context_t nrf_crypto_ecdsa_bp512r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdsa_bp512r1 */
+typedef nrf_crypto_backend_curve25519_verify_context_t nrf_crypto_ecdsa_curve25519_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve Curve25519. @ingroup nrf_crypto_ecdsa_curve25519 */
+typedef nrf_crypto_backend_ed25519_verify_context_t nrf_crypto_ecdsa_ed25519_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve Ed25519. @ingroup nrf_crypto_ecdsa_ed25519 */
+
+
+/** @brief Union holding a context for ECDSA hash sign.
+ */
+typedef union
+{
+ nrf_crypto_ecdsa_secp160r1_sign_context_t context_secp160r1; /**< @brief Occupies space for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp160r2_sign_context_t context_secp160r2; /**< @brief Occupies space for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp192r1_sign_context_t context_secp192r1; /**< @brief Occupies space for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecdsa_secp224r1_sign_context_t context_secp224r1; /**< @brief Occupies space for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecdsa_secp256r1_sign_context_t context_secp256r1; /**< @brief Occupies space for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecdsa_secp384r1_sign_context_t context_secp384r1; /**< @brief Occupies space for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecdsa_secp521r1_sign_context_t context_secp521r1; /**< @brief Occupies space for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecdsa_secp160k1_sign_context_t context_secp160k1; /**< @brief Occupies space for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecdsa_secp192k1_sign_context_t context_secp192k1; /**< @brief Occupies space for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecdsa_secp224k1_sign_context_t context_secp224k1; /**< @brief Occupies space for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecdsa_secp256k1_sign_context_t context_secp256k1; /**< @brief Occupies space for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecdsa_bp256r1_sign_context_t context_bp256r1; /**< @brief Occupies space for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecdsa_bp384r1_sign_context_t context_bp384r1; /**< @brief Occupies space for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecdsa_bp512r1_sign_context_t context_bp512r1; /**< @brief Occupies space for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecdsa_curve25519_sign_context_t context_curve25519; /**< @brief Occupies space for Curve25519. */
+ nrf_crypto_ecdsa_ed25519_sign_context_t context_ed25519; /**< @brief Occupies space for Ed25519. */
+} nrf_crypto_ecdsa_sign_context_t;
+
+
+/** @brief Union holding a context for ECDSA hash verify.
+ */
+typedef union
+{
+ nrf_crypto_ecdsa_secp160r1_verify_context_t context_secp160r1; /**< @brief Occupies spece for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp160r2_verify_context_t context_secp160r2; /**< @brief Occupies spece for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp192r1_verify_context_t context_secp192r1; /**< @brief Occupies spece for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecdsa_secp224r1_verify_context_t context_secp224r1; /**< @brief Occupies spece for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecdsa_secp256r1_verify_context_t context_secp256r1; /**< @brief Occupies spece for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecdsa_secp384r1_verify_context_t context_secp384r1; /**< @brief Occupies spece for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecdsa_secp521r1_verify_context_t context_secp521r1; /**< @brief Occupies spece for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecdsa_secp160k1_verify_context_t context_secp160k1; /**< @brief Occupies spece for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecdsa_secp192k1_verify_context_t context_secp192k1; /**< @brief Occupies spece for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecdsa_secp224k1_verify_context_t context_secp224k1; /**< @brief Occupies spece for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecdsa_secp256k1_verify_context_t context_secp256k1; /**< @brief Occupies spece for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecdsa_bp256r1_verify_context_t context_bp256r1; /**< @brief Occupies spece for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecdsa_bp384r1_verify_context_t context_bp384r1; /**< @brief Occupies spece for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecdsa_bp512r1_verify_context_t context_bp512r1; /**< @brief Occupies spece for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecdsa_curve25519_verify_context_t context_curve25519; /**< @brief Occupies spece for Curve25519. */
+ nrf_crypto_ecdsa_ed25519_verify_context_t context_ed25519; /**< @brief Occupies spece for Ed25519. */
+} nrf_crypto_ecdsa_verify_context_t;
+
+
+/** @brief Sign a hash of a message.
+ *
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_private_key Pointer to structure holding a private key.
+ * @param[in] p_hash Pointer to hash to sign.
+ * @param[in] hash_size Number of bytes in p_hash.
+ * @param[out] p_signature Pointer to buffer where digital signature will be put.
+ * @param[in,out] p_signature_size Maximum number of bytes that @p p_signature buffer can hold on input
+ * and the actual number of bytes used by the data on output.
+ * Actual size for selected curve is defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE.
+ */
+ret_code_t nrf_crypto_ecdsa_sign(
+ nrf_crypto_ecdsa_sign_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t * p_signature,
+ size_t * p_signature_size);
+
+
+/** @brief Verify a signature using a hash of a message.
+ *
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_public_key Pointer to structure holding a public key.
+ * @param[in] p_hash Pointer to hash to verify.
+ * @param[in] hash_size Number of bytes in p_hash.
+ * @param[in] p_signature Pointer to buffer containing digital signature.
+ * @param[in,out] signature_size Number of bytes in p_signature.
+ */
+ret_code_t nrf_crypto_ecdsa_verify(
+ nrf_crypto_ecdsa_verify_context_t * p_context,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t const * p_signature,
+ size_t signature_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}
+ * @}
+ */
+
+#endif // NRF_CRYPTO_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h
new file mode 100644
index 0000000..78bd2a0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDSA_BACKEND_H__
+#define NRF_CRYPTO_ECDSA_BACKEND_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_config.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+// Include all backends
+#include "cc310_backend_ecdsa.h"
+#include "cc310_bl_backend_ecdsa.h"
+#include "mbedtls_backend_ecdsa.h"
+#include "oberon_backend_ecdsa.h"
+#include "micro_ecc_backend_ecdsa.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp160r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp160r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r1_sign NULL
+#define nrf_crypto_backend_secp160r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp160r2_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp160r2_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r2_sign NULL
+#define nrf_crypto_backend_secp160r2_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp192r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192r1_sign NULL
+#define nrf_crypto_backend_secp192r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp224r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224r1_sign NULL
+#define nrf_crypto_backend_secp224r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp256r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256r1_sign NULL
+#define nrf_crypto_backend_secp256r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp384r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp384r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp384r1_sign NULL
+#define nrf_crypto_backend_secp384r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp521r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp521r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp521r1_sign NULL
+#define nrf_crypto_backend_secp521r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp160k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp160k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160k1_sign NULL
+#define nrf_crypto_backend_secp160k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp192k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp192k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192k1_sign NULL
+#define nrf_crypto_backend_secp192k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp224k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp224k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224k1_sign NULL
+#define nrf_crypto_backend_secp224k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp256k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256k1_sign NULL
+#define nrf_crypto_backend_secp256k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_bp256r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_bp256r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp256r1_sign NULL
+#define nrf_crypto_backend_bp256r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_bp384r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_bp384r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp384r1_sign NULL
+#define nrf_crypto_backend_bp384r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_bp512r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_bp512r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp512r1_sign NULL
+#define nrf_crypto_backend_bp512r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_curve25519_sign_context_t;
+typedef uint8_t nrf_crypto_backend_curve25519_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_curve25519_sign NULL
+#define nrf_crypto_backend_curve25519_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_ed25519_sign_context_t;
+typedef uint8_t nrf_crypto_backend_ed25519_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_ed25519_sign NULL
+#define nrf_crypto_backend_ed25519_verify NULL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECDSA_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h
new file mode 100644
index 0000000..70d81ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDSA_SHARED_H__
+#define NRF_CRYPTO_ECDSA_SHARED_H__
+
+#include <stdint.h>
+
+#include "nordic_common.h"
+#include "nrf_crypto_ecc.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Function pointer for backend implementation of ECDSA sign.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_private_key Pointer to private key.
+ * @param[in] p_data Pointer to data to sign. Data can be a message or a hash. It depends
+ * on which version of signing functions is pointed by this function
+ * pointer.
+ * @param[in] data_size Size of @p p_data.
+ * @param[out] p_signature Pointer where to put generated signature.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecdsa_sign_fn_t)(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal @brief Function pointer for backend implementation of ECDSA verify.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_public_key Pointer to public key.
+ * @param[in] p_data Pointer to data to verify. Data can be a message or a hash. It depends
+ * on which version of signing functions is pointed by this function
+ * pointer.
+ * @param[in] data_size Size of @p p_data.
+ * @param[in] p_signature Pointer to signature to verify.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecdsa_verify_fn_t)(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_ECDSA_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c
new file mode 100644
index 0000000..9a37b01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nordic_common.h"
+#include "nrf_crypto_error.h"
+
+typedef struct
+{
+ ret_code_t error;
+ const char * p_text;
+} error_code_pair;
+
+static const error_code_pair m_crypto_error[] =
+{
+ { NRF_ERROR_CRYPTO_NOT_INITIALIZED, "nrf_crypto_init was not called prior to this crypto function" },
+ { NRF_ERROR_CRYPTO_CONTEXT_NULL, "A null pointer was provided for the context structure" },
+ { NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED, "The context was not initialized prior to this call or it was corrupted. Please call the corresponding init function for the algorithm to initialize it" },
+ { NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE, "The function was called with a feature that is unavailable" },
+ { NRF_ERROR_CRYPTO_BUSY, "The function could not be called because the crypto backend was busy. Please rerun the cryptographic routine at a later time" },
+ { NRF_ERROR_CRYPTO_INPUT_NULL, "One or more of the input arguments for this function was NULL" },
+ { NRF_ERROR_CRYPTO_INPUT_LENGTH, "The length of one or more of the input arguments was invalid" },
+ { NRF_ERROR_CRYPTO_INPUT_LOCATION, "Input data not in RAM" },
+ { NRF_ERROR_CRYPTO_OUTPUT_NULL, "One or more of the output arguments for this function was NULL" },
+ { NRF_ERROR_CRYPTO_OUTPUT_LENGTH, "The length of the one or more output arguments was too small" },
+ { NRF_ERROR_CRYPTO_ALLOC_FAILED, "A required memory allocation failed" },
+ { NRF_ERROR_CRYPTO_INTERNAL, "An internal error occurred when calling this function" },
+ { NRF_ERROR_CRYPTO_INVALID_PARAM, "Invalid combination of input parameters" },
+ { NRF_ERROR_CRYPTO_KEY_SIZE, "Size of the key is not supported by choosen backend" },
+ { NRF_ERROR_CRYPTO_STACK_OVERFLOW, "Stack overflow detected" },
+ { NRF_ERROR_CRYPTO_ECC_KEY_NOT_INITIALIZED, "ECC key was not initialized" },
+ { NRF_ERROR_CRYPTO_ECDH_CURVE_MISMATCH, "Public and private key provided to ECDH have different types of curves" },
+ { NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE, "Signature verification check reported invalid signature" },
+ { NRF_ERROR_CRYPTO_ECC_INVALID_KEY, "Provided key is invalid" },
+ { NRF_ERROR_CRYPTO_AES_INVALID_PADDING, "Message padding is corrupted." },
+ { NRF_ERROR_CRYPTO_AEAD_INVALID_MAC, "MAC not matching encrypted text" },
+ { NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE, "Size of the nonce is not supported in this AEAD mode" },
+ { NRF_ERROR_CRYPTO_AEAD_MAC_SIZE, "Size of the MAC (tag) is not supported in this AEAD mode" },
+ { NRF_ERROR_CRYPTO_RNG_INIT_FAILED, "Initialization or startup of RNG failed" },
+ { NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED, "Reseed required (reseed counter overflowed)" },
+};
+
+char const * nrf_crypto_error_string_get(ret_code_t error)
+{
+ if (error == NRF_SUCCESS)
+ {
+ return "No error";
+ }
+ else
+ {
+ uint32_t i;
+ for (i = 0; i < ARRAY_SIZE(m_crypto_error); i++)
+ {
+ if (m_crypto_error[i].error == error)
+ {
+ return m_crypto_error[i].p_text;
+ }
+ }
+ }
+ return "Error not related to nrf_crypto library";
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h
new file mode 100644
index 0000000..970f5fb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ERROR_H__
+#define NRF_CRYPTO_ERROR_H__
+
+/**@file
+ *
+ * @defgroup nrf_crypto_error nrf_crypto error codes
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @details This is the standardized error codes provided when calling nrf_crypto APIs.
+ * The error codes provided here are enumerated based on @ref NRF_ERROR_CRYPTO_ERR_BASE.
+ *
+ * @note Success code, NRF_SUCCESS, is used if the nrf_crypto operation was successful.
+ *
+ */
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_ERROR_CRYPTO_NOT_INITIALIZED (NRF_ERROR_CRYPTO_ERR_BASE + 0x00) /**< @ref nrf_crypto_init was not called prior to this crypto function. */
+#define NRF_ERROR_CRYPTO_CONTEXT_NULL (NRF_ERROR_CRYPTO_ERR_BASE + 0x01) /**< A null pointer was provided for the context structure. */
+#define NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED (NRF_ERROR_CRYPTO_ERR_BASE + 0x02) /**< The context was not initialized prior to this call or it was corrupted. Call the corresponding init function for the algorithm to initialize it. */
+#define NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE (NRF_ERROR_CRYPTO_ERR_BASE + 0x03) /**< The function was called with a feature that is unavailable. */
+#define NRF_ERROR_CRYPTO_BUSY (NRF_ERROR_CRYPTO_ERR_BASE + 0x04) /**< The function could not be called because the crypto backend was busy. Rerun the cryptographic routine at a later time. */
+
+#define NRF_ERROR_CRYPTO_INPUT_NULL (NRF_ERROR_CRYPTO_ERR_BASE + 0x10) /**< One or more of the input arguments for this function were NULL. */
+#define NRF_ERROR_CRYPTO_INPUT_LENGTH (NRF_ERROR_CRYPTO_ERR_BASE + 0x11) /**< The length of one or more of the input arguments was invalid. */
+#define NRF_ERROR_CRYPTO_INPUT_LOCATION (NRF_ERROR_CRYPTO_ERR_BASE + 0x12) /**< Input data not in RAM. */
+#define NRF_ERROR_CRYPTO_OUTPUT_NULL (NRF_ERROR_CRYPTO_ERR_BASE + 0x13) /**< One or more of the output arguments for this function were NULL. */
+#define NRF_ERROR_CRYPTO_OUTPUT_LENGTH (NRF_ERROR_CRYPTO_ERR_BASE + 0x14) /**< The length of one or more output arguments was too small. */
+#define NRF_ERROR_CRYPTO_ALLOC_FAILED (NRF_ERROR_CRYPTO_ERR_BASE + 0x15) /**< A required memory allocation failed. */
+#define NRF_ERROR_CRYPTO_INTERNAL (NRF_ERROR_CRYPTO_ERR_BASE + 0x16) /**< An internal error occurred when calling this function. */
+#define NRF_ERROR_CRYPTO_INVALID_PARAM (NRF_ERROR_CRYPTO_ERR_BASE + 0x17) /**< Invalid combination of input parameters. */
+#define NRF_ERROR_CRYPTO_KEY_SIZE (NRF_ERROR_CRYPTO_ERR_BASE + 0x18) /**< Size of the key is not supported by choosen backend. */
+#define NRF_ERROR_CRYPTO_STACK_OVERFLOW (NRF_ERROR_CRYPTO_ERR_BASE + 0x19) /**< Stack overflow detected. */
+
+#define NRF_ERROR_CRYPTO_ECC_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x40) /**< Base error code for ECC. */
+#define NRF_ERROR_CRYPTO_ECC_KEY_NOT_INITIALIZED (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x00) /**< The key was not initialized. */
+#define NRF_ERROR_CRYPTO_ECDH_CURVE_MISMATCH (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x01) /**< Public and private key provided to ECDH have different types of curves. */
+#define NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x02) /**< Signature verification check reported invalid signature. */
+#define NRF_ERROR_CRYPTO_ECC_INVALID_KEY (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x03) /**< Provided key is invalid. */
+
+#define NRF_ERROR_CRYPTO_AES_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x50) /**< Base error code for all AES modes. */
+#define NRF_ERROR_CRYPTO_AES_INVALID_PADDING (NRF_ERROR_CRYPTO_AES_ERR_BASE + 0x00) /**< Message padding is corrupted. */
+
+#define NRF_ERROR_CRYPTO_AEAD_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x60) /**< Base error code for all AEAD modes. */
+#define NRF_ERROR_CRYPTO_AEAD_INVALID_MAC (NRF_ERROR_CRYPTO_AEAD_ERR_BASE + 0x00) /**< MAC not matching encrypted text. */
+#define NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE (NRF_ERROR_CRYPTO_AEAD_ERR_BASE + 0x01) /**< Size of the nonce is not supported in this AEAD mode. */
+#define NRF_ERROR_CRYPTO_AEAD_MAC_SIZE (NRF_ERROR_CRYPTO_AEAD_ERR_BASE + 0x02) /**< Size of the MAC (tag) is not supported in this AEAD mode. */
+
+#define NRF_ERROR_CRYPTO_RNG_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x70) /**< Base error code for all RNG modes. */
+#define NRF_ERROR_CRYPTO_RNG_INIT_FAILED (NRF_ERROR_CRYPTO_RNG_ERR_BASE + 0x00) /**< Initialization or startup of RNG failed. */
+#define NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED (NRF_ERROR_CRYPTO_RNG_ERR_BASE + 0x01) /**< Reseed required (reseed counter overflowed). */
+
+/**
+ * @brief Function for converting an nrf_crypto error to a printable string pointer.
+ *
+ * @param[in] error Error code.
+ *
+ * @return Pointer to string explaining nrf_crypto error.
+ * */
+char const * nrf_crypto_error_string_get(ret_code_t error);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // NRF_CRYPTO_ERROR_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c
new file mode 100644
index 0000000..a03a9ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_hash_backend.h"
+#include "nrf_crypto_hash_shared.h"
+#include "nrf_crypto_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH)
+
+static ret_code_t verify_context(nrf_crypto_hash_internal_context_t * const p_context)
+{
+ if (p_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ }
+
+ if (p_context->init_val != NRF_CRYPTO_HASH_INIT_VALUE)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_hash_init(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_internal_context_t * p_int_context;
+
+ VERIFY_TRUE(p_context != NULL, NRF_ERROR_CRYPTO_CONTEXT_NULL);
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ p_int_context = (nrf_crypto_hash_internal_context_t *) p_context;
+ p_int_context->p_info = p_info;
+
+ ret_val = p_info->init_fn(p_context);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ p_int_context->init_val = NRF_CRYPTO_HASH_INIT_VALUE;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_hash_update(nrf_crypto_hash_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_internal_context_t * p_int_context
+ = (nrf_crypto_hash_internal_context_t *) p_context;
+
+ ret_val = verify_context(p_int_context);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ VERIFY_TRUE(p_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Allow zero size input
+ if (data_size == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ ret_val = p_int_context->p_info->update_fn(p_context, p_data, data_size);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_hash_finalize(nrf_crypto_hash_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_internal_context_t * p_int_context
+ = (nrf_crypto_hash_internal_context_t *) p_context;
+
+ ret_val = verify_context(p_int_context);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ VERIFY_TRUE(p_digest != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(*p_digest_size >= p_int_context->p_info->digest_size, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ ret_val = p_int_context->p_info->finalize_fn(p_context, p_digest, p_digest_size);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_hash_calculate(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_context_t * p_ctx = (nrf_crypto_hash_context_t *)p_context;
+ void * p_allocated_context = NULL;
+
+// Internal allocation of context not available for CC310_BL in order to save code size.
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED == 1)
+
+ // Do nothing
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED == 0)
+
+ // Validate input. Only validate input parameters that are used locally, others are validated
+ // in the init, update and/or finalize functions.
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Allocate context if needed (not provided by the user).
+ if (p_context == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = (nrf_crypto_hash_context_t *)p_allocated_context;
+ }
+
+#else
+
+ #warning NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED
+
+ ret_val = nrf_crypto_hash_init(p_ctx, p_info);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_hash_update(p_ctx, p_data, data_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_hash_finalize(p_ctx, p_digest, p_digest_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+ // Free context if allocated internally
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+#endif // !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_HASH)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h
new file mode 100644
index 0000000..66159b4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HASH_H__
+#define NRF_CRYPTO_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hash Cryptographic hash related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides cryptographic hash related functionality through nrf_crypto.
+ */
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_hash_shared.h"
+#include "nrf_crypto_hash_backend.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief External variable declaration to info structure for SHA-256
+ *
+ * @note The variable is defined in the nrf_crypto backend that is
+ * enabled in the @ref sdk_config.
+ *
+ */
+extern const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info;
+
+
+ /**@brief External variable declaration to info structure for SHA-512
+ *
+ * @note The variable is defined in the nrf_crypto backend that is
+ * enabled in the @ref sdk_config.
+ *
+ */
+extern const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info;
+
+
+/**
+ * @brief Context type for Hash.
+ *
+ * @note The size of this type is scaled for the largest Hash backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_hash_context_t nrf_crypto_hash_context_t;
+
+
+/** @brief Type definition for an array holding a SHA-256 hash digest. */
+typedef uint8_t nrf_crypto_hash_sha256_digest_t[NRF_CRYPTO_HASH_SIZE_SHA256];
+
+
+/** @brief Type definition for an array holding a SHA-512 hash digest. */
+typedef uint8_t nrf_crypto_hash_sha512_digest_t[NRF_CRYPTO_HASH_SIZE_SHA512];
+
+
+/**@brief Function for initializing the context structure required to compute a hash digest from
+ * arbitrary input data.
+ *
+ * @note The context structure is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return codes @ref NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE and
+ * NRF_ERROR_CRYPTO_INTERNAL only happens in cc310 backend.
+ *
+ * @param[in,out] p_context Pointer to structure holding context information for
+ * the hash calculation.
+ * @param[in] p_info Pointer to structure holding info about the hash algorithm
+ * used to do the computed hash.
+ *
+ * @retval NRF_SUCCESS The hash initialization was successful.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL The pointer to the info structure was NULL.
+ * @retval NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE The function was called with a hash mode that
+ * is unavailable.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred when initializing
+ * the constext in the nrf_crypto backend.
+ */
+ret_code_t nrf_crypto_hash_init(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info);
+
+
+/**@brief Function for updating the hash calculation with partial arbitrary data.
+ *
+ * @details This function should be called one or more times until all arbituary input data
+ * required for the hash calcuation is provided.
+ *
+ * @note @ref nrf_crypto_hash_init must be called prior to this function to configure the
+ * context structure used as input parameter to this function.
+ *
+ * @note @ref nrf_crypto_hash_finalize must be called after all arbitruary input data
+ * has been provided to get the calculated hash digest.
+ *
+ * @note The context object is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return values @ref NRF_ERROR_CRYPTO_BUSY, @ref NRF_ERROR_CRYPTO_INPUT_LOCATION
+ * and @ref NRF_ERROR_CRYPTO_INPUT_LOCATION can only occur in CC310 backend.
+ *
+ * @param[in,out] p_context Pointer to structure holding context information for
+ * the hash calculation.
+ * @param[in] p_data Pointer to data to be hashed.
+ * @param[in] data_size Length of the data to be hashed.
+ *
+ * @retval NRF_SUCCESS The hash digest was computed successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED The context was not initialized prior to
+ * this call or it was corrupted. Please call
+ * @ref nrf_crypto_hash_init to initialize it.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred in the nrf_crypto
+ * backend.
+ */
+ret_code_t nrf_crypto_hash_update(nrf_crypto_hash_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size);
+
+/**@brief Function for finalizing computation of a hash digest from arbitrary data.
+ *
+ * @details This function is called to get the calculated
+ *
+ * @note @ref nrf_crypto_hash_init must be called prior to this function to configure the
+ * context structure used as input parameter to this function.
+ *
+ * @note The input data for the calculated hash digest must be provided by calling
+ * @ref nrf_crypto_hash_update one or more times.
+ *
+ * @note The context object is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return values @ref NRF_ERROR_CRYPTO_BUSY and @ref NRF_ERROR_CRYPTO_INPUT_LOCATION
+ * can only occur in CC310 backend.
+ *
+ *
+ * @param[in] p_context Pointer to structure holding context information for
+ * the hash calculation.
+ * @param[out] p_digest Pointer to buffer holding the calculated hash digest.
+ * @param[in,out] p_digest_size Pointer to a variable holding the length of the calculated hash.
+ * Set this to the length of buffer that p_digest is pointing to.
+ *
+ * @retval NRF_SUCCESS The hash digest was computed successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED The context was not initialized prior to
+ * this call or it was corrupted. Please call
+ * @ref nrf_crypto_hash_init to initialize it.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_digest or p_digest_size was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH The length of p_digest was too small for
+ * the hash digest result.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred in the nrf_crypto
+ * backend.
+ */
+ret_code_t nrf_crypto_hash_finalize(nrf_crypto_hash_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+
+/**@brief Function for computing a hash from arbitrary data in a single integrated step.
+ *
+ * @details This function calculates the hash digest from arbitruary data in a single integrated step.
+ * This means calling init, update and finalize in one step.
+ *
+ * @note The context object is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return values @ref NRF_ERROR_CRYPTO_BUSY, @ref NRF_ERROR_CRYPTO_INPUT_LOCATION
+ * and @ref NRF_ERROR_CRYPTO_INPUT_LOCATION can only occur in CC310 backend.
+ *
+ * @param[in,out] p_context Pointer to structure holding context information for
+ * the hash calculation. If this
+ * is set to NULL, it will be allocated by the user configurable
+ * allocate/free function @ref NRF_CRYPTO_ALLOC and
+ * @ref NRF_CRYPTO_FREE.
+ * @param[in] p_info Pointer to structure holding info about hash algorithm
+ * for the computed hash.
+ * @param[in] p_data Pointer to data to be hashed.
+ * @param[in] data_size Length of the data to be hashed.
+ * @param[out] p_digest Pointer to buffer holding the calculated hash digest.
+ * @param[in,out] p_digest_size Pointer to a variable holding the length of the calculated hash.
+ * Set this to the length of buffer that p_digest is pointing to.
+ *
+ * @retval NRF_SUCCESS The hash initialization was successful.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_info or p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_digest or p_digest_size was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH The length of p_digest was too small for
+ * the hash digest result.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred in the nrf_crypto
+ * backend.
+ */
+ret_code_t nrf_crypto_hash_calculate(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h
new file mode 100644
index 0000000..2fbac07
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HASH_BACKEND_H__
+#define NRF_CRYPTO_HASH_BACKEND_H__
+
+#include "sdk_common.h"
+#include "cc310_backend_hash.h"
+#include "mbedtls_backend_hash.h"
+#include "oberon_backend_hash.h"
+#include "cc310_bl_backend_hash.h"
+#include "nrf_sw_backend_hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+
+/**@internal @brief Fallback type for SHA-256 hash context (if no backend is enabled).
+ */
+typedef nrf_crypto_hash_internal_context_t nrf_crypto_backend_hash_sha256_context_t;
+
+#endif
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+
+/**@internal @brief Fallback type for SHA-512 hash context (if no backend is enabled).
+ */
+typedef nrf_crypto_hash_internal_context_t nrf_crypto_backend_hash_sha512_context_t;
+
+#endif
+
+
+/** @internal @brief Union holding a hash context. */
+typedef union
+{
+ nrf_crypto_backend_hash_sha256_context_t hash_sha256_context; /**< @brief Holds context for SHA-256. */
+ nrf_crypto_backend_hash_sha512_context_t hash_sha512_context; /**< @brief Holds context for SHA-512. */
+} nrf_crypto_backend_hash_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_HASH_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h
new file mode 100644
index 0000000..14205d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HASH_SHARED_H__
+#define NRF_CRYPTO_HASH_SHARED_H__
+
+#include "stdint.h"
+#include "stddef.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_HASH_INIT_VALUE (0x4846526E) //!< Magic value to signal that the nrf_crypto_hash context structure is initialized.
+
+/**@brief Enumeration of supported modes of operation in nrf_crypto_hash
+ */
+typedef enum
+{
+ NRF_CRYPTO_HASH_MODE_SHA256,
+ NRF_CRYPTO_HASH_MODE_SHA512
+} nrf_crypto_hash_mode_t;
+
+
+/**@internal @brief Type declaration to do hash initialization in nrf_crypto backend.
+ *
+ * This is an internal API. See @ref nrf_crypto_hash_init for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_hash_init_fn_t)(void * const p_context);
+
+
+/**@internal @brief Type declaration to do hash update in nrf_crypto backend.
+ *
+ * This is an internal API. See @ref nrf_crypto_hash_init for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_hash_update_fn_t)(void * const p_context,
+ uint8_t const * p_data,
+ size_t size);
+
+
+/**@internal @brief Type declaration to do hash finalize in nrf_crypto backend.
+ *
+ * This is an internal API. See @ref nrf_crypto_hash_finalize for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_hash_finalize_fn_t)(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+
+/**@internal @brief Type declaration to for a nrf_crypto_hash info strucure
+ *
+ * @details This structure contains the calling interface and any meta data required
+ * to call the nrf_crypto_hash API functions.
+ */
+typedef struct
+{
+ nrf_crypto_hash_init_fn_t const init_fn; /**< Function pointer to call to initialize nrf_crypto_hash context in backend. */
+ nrf_crypto_hash_update_fn_t const update_fn; /**< Function pointer to call to add data in the hash calculation. */
+ nrf_crypto_hash_finalize_fn_t const finalize_fn; /**< Function pointer to call to finalize the hash calculation and return the result. */
+ size_t const digest_size; /**< Size of the digest. */
+ size_t const context_size; /**< Size of the context type. */
+ nrf_crypto_hash_mode_t const hash_mode; /**< Mode of hash operation. */
+} nrf_crypto_hash_info_t;
+
+
+/**@internal @brief Type declaration of internal representation of a hash context structure.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_val; /**< Value that is set to NRF_CRYPTO_HASH_INIT_VALUE when context has been initialized. */
+ nrf_crypto_hash_info_t const * p_info; /**< Pointer to an nrf_crypto_hash info structure. */
+
+} nrf_crypto_hash_internal_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_HASH_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c
new file mode 100644
index 0000000..00c6c7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "stddef.h"
+#include "nrf_assert.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hkdf.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_hmac_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+
+static ret_code_t hkdf_expand(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * const p_output_key,
+ size_t output_key_size,
+ uint8_t const * const p_ainfo,
+ size_t ainfo_size,
+ uint8_t * const p_temp,
+ uint8_t const * const p_prk,
+ size_t prk_size)
+{
+ size_t const hash_digest_size = p_info->digest_size;
+ uint32_t const n_iterations = (output_key_size + hash_digest_size - 1) / hash_digest_size;
+ ret_code_t err_code = NRF_SUCCESS;
+ size_t temp_size;
+ uint8_t n_current;
+ int write_offset;
+
+ VERIFY_TRUE(n_iterations <= 255, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ write_offset = 0;
+ for (uint32_t i = 0; i < n_iterations; i++)
+ {
+ n_current = i + 1;
+
+ err_code = nrf_crypto_hmac_init(p_context, p_info, p_prk, prk_size);
+ VERIFY_SUCCESS(err_code);
+
+ if (i != 0)
+ {
+ err_code = nrf_crypto_hmac_update(p_context, p_temp, hash_digest_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ if (p_ainfo != NULL)
+ {
+ err_code = nrf_crypto_hmac_update(p_context, p_ainfo, ainfo_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ err_code = nrf_crypto_hmac_update(p_context, &n_current, 1);
+ VERIFY_SUCCESS(err_code);
+
+ temp_size = hash_digest_size;
+ err_code = nrf_crypto_hmac_finalize(p_context, p_temp, &temp_size);
+ VERIFY_SUCCESS(err_code);
+
+ memcpy(p_output_key + write_offset,
+ p_temp,
+ (n_current != n_iterations) ? hash_digest_size : (output_key_size - write_offset));
+
+ write_offset += hash_digest_size;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hkdf_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * const p_output_key,
+ size_t * const p_output_key_size,
+ uint8_t const * const p_input_key,
+ size_t input_key_size,
+ uint8_t const * p_salt,
+ size_t salt_size,
+ uint8_t const * const p_ainfo,
+ size_t ainfo_size,
+ nrf_crypto_hkdf_mode_t mode)
+{
+ uint8_t prk[NRF_CRYPTO_HASH_SIZE_SHA512]; // Scaled for the largest supported hash size.
+ uint8_t temp[NRF_CRYPTO_HASH_SIZE_SHA512]; // Scaled for the largest supported hash size.
+ void * p_ctx = NULL;
+ void * p_allocated_context = NULL;
+ size_t prk_size = sizeof(prk);
+ size_t output_key_size = *p_output_key_size;
+ ret_code_t err_code;
+
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_output_key != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(*p_output_key_size > 0, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+ VERIFY_TRUE(p_input_key != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(input_key_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ if (p_salt != NULL)
+ {
+ VERIFY_TRUE(salt_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ }
+
+ if (p_ainfo != NULL)
+ {
+ VERIFY_TRUE(ainfo_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ }
+
+ *p_output_key_size = 0; // Set output length to 0 as default value (in case of error).
+
+ // Allocate context internally if p_context is NULL
+ if (p_context == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = p_allocated_context;
+ }
+ else
+ {
+ p_ctx = p_context;
+ }
+
+ if (mode == NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND)
+ {
+ if (p_salt == NULL)
+ {
+ // Use default salt defined in RFC 5869: String of zeros of hash length.
+ salt_size = p_info->digest_size;
+ ASSERT(sizeof(temp) >= salt_size);
+ memset(temp, 0, salt_size);
+ p_salt = temp;
+ }
+
+ // Step 1: Extract
+ err_code = nrf_crypto_hmac_calculate(p_context,
+ p_info,
+ prk,
+ &prk_size,
+ p_salt,
+ salt_size,
+ p_input_key,
+ input_key_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ // Step 2: Expand
+ err_code = hkdf_expand(p_ctx,
+ p_info,
+ p_output_key,
+ output_key_size,
+ p_ainfo,
+ ainfo_size,
+ temp,
+ prk,
+ prk_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+ }
+ else // NRF_CRYPTO_HKDF_EXPAND_ONLY
+ {
+ err_code = hkdf_expand(p_ctx,
+ p_info,
+ p_output_key,
+ output_key_size,
+ p_ainfo,
+ ainfo_size,
+ temp,
+ p_input_key,
+ input_key_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+ }
+
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ *p_output_key_size = output_key_size;
+
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h
new file mode 100644
index 0000000..7c84615
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HKDF_H__
+#define NRF_CRYPTO_HKDF_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hkdf HMAC based Key Derivation Function (HKDF) related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides functions to generate HMAC based Key Derivation Function (HKDF).
+ *
+ * @details Provides functions to generate HMAC based Key Derivation Function (HKDF) using
+ * one of the supported hash algorithms. This layer is independent of backend crypto library.
+ * The HKDF module does not have a backend configuration, as it uses the nrf_crypto_hmac API,
+ * including the backend configured for HMAC in @ref sdk_config.
+ */
+
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hkdf.h"
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Enumeration of HKDF modes.
+ */
+typedef enum
+{
+ NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND, //!< HKDF Extract and expand mode (normal).
+ NRF_CRYPTO_HKDF_EXPAND_ONLY //!< HKDF Expand only mode.
+} nrf_crypto_hkdf_mode_t;
+
+
+/**
+ * @brief Integrated HKDF calculation function
+ *
+ * @details This HKDF calculation function uses the nrf_crypto HMAC frontend directly.
+ * The backend is selected by configuring the HMAC backend in @ref sdk_config.
+ *
+ * @param[in,out] p_context Pointer to context structure. Context memory will be
+ * allocated internally if the context pointer is NULL.
+ * @param[in] p_info Pointer to static info structure. This defines the algorithm.
+ * This should be either @ref g_nrf_crypto_hmac_sha256_info or
+ * @ref g_nrf_crypto_hmac_sha512_info.
+ * @param[out] p_output_key Pointer to buffer to hold the output key material.
+ * @param[in,out] p_output_key_size Pointer to the length of the wanted output key material as input
+ * and actual length of the output material as output. Can be any
+ * number between 1 and the hash digest size multiplied by 255
+ * (65280 for SHA-256 or 130560 for SHA-512). The p_output_key
+ * buffer must be large enough to hold this value.
+ * @param[in] p_input_key Pointer to buffer holding the input key material.
+ * @param[in] input_key_size Length of the input key material.
+ * @param[in] p_salt Pointer to buffer of nonsecret random salt data. Set to NULL in
+ * order to use the default salt defined by RFC 5869 (all zero
+ * array of hash digest size) or if salt is not used (expand only).
+ * @param[in] salt_size Length of the salt. Must be > 0 unless default salt is used, or
+ * in case mode is set to @ref NRF_CRYPTO_HKDF_EXPAND_ONLY.
+ * @param[in] p_ainfo Pointer to optional application specific information.
+ * (set to NULL and set ainfo_size to 0 if unused).
+ * @param[in] ainfo_size Length of the additional information.
+ * @param[in] mode Set to @ref NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND for normal mode.
+ * Alternatively, set to @ref NRF_CRYPTO_HKDF_EXPAND_ONLY to skip
+ * the extraction step.
+ *
+ * @retval NRF_SUCCESS Output key material hash was successfully calculated.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_input_key was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If input_key_size or salt_size was invalid.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL If p_output_key_sizen was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH If *p_output_key_size is 0.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time. CC310 only.
+ */
+ret_code_t nrf_crypto_hkdf_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * const p_output_key,
+ size_t * const p_output_key_size,
+ uint8_t const * const p_input_key,
+ size_t input_key_size,
+ uint8_t const * p_salt,
+ size_t salt_size,
+ uint8_t const * const p_ainfo,
+ size_t ainfo_size,
+ nrf_crypto_hkdf_mode_t mode);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // #ifndef NRF_CRYPTO_HKDF_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c
new file mode 100644
index 0000000..4bd1546
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "stddef.h"
+#include "nrf_log.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hmac_shared.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+
+// Magic word that is set when initializing the context and checked by functions that use it.
+#define NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE 0xBADEBA11
+
+
+static ret_code_t verify_context_valid(nrf_crypto_hmac_internal_context_t * const p_context)
+{
+ if (p_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ }
+ else if (p_context->init_value != NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+ret_code_t nrf_crypto_hmac_init(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ ret_code_t err_code;
+ nrf_crypto_hmac_internal_context_t * p_ctx = (nrf_crypto_hmac_internal_context_t *)p_context;
+
+ VERIFY_TRUE(nrf_crypto_is_initialized(), NRF_ERROR_CRYPTO_NOT_INITIALIZED);
+
+ // Validate input
+ VERIFY_TRUE(p_ctx != NULL, NRF_ERROR_CRYPTO_CONTEXT_NULL);
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_key != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(key_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ // Initialize generic part of the context
+ p_ctx->p_info = p_info;
+
+ // Do backend specific initialization by calling the backend init function pointed
+ // to in the configuration struct in the context (nrf_crypto_hmac_config_t)
+ err_code = p_ctx->p_info->init_fn(p_context, p_key, key_size);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ctx->init_value = NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hmac_update(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size)
+{
+ ret_code_t err_code;
+
+ // The context header by definition has to be the first element of the context struct.
+ nrf_crypto_hmac_internal_context_t * p_ctx = (nrf_crypto_hmac_internal_context_t *)p_context;
+
+ // Validate input
+ err_code = verify_context_valid(p_ctx);
+ VERIFY_SUCCESS(err_code);
+ VERIFY_TRUE(p_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(data_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ // Call backend specific update function (pointed to by config struct in context)
+ err_code = p_ctx->p_info->update_fn(p_context, p_data, data_size);
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hmac_finalize(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t err_code;
+
+ // The context header by definition has to be the first element of the context struct.
+ nrf_crypto_hmac_internal_context_t * p_ctx = (nrf_crypto_hmac_internal_context_t *)p_context;
+
+ // Validate input
+ err_code = verify_context_valid(p_ctx);
+ VERIFY_SUCCESS(err_code);
+ VERIFY_TRUE(p_digest != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(*p_digest_size >= p_ctx->p_info->digest_size, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ // Call backend specific finish function (pointed to by config struct in context)
+ err_code = p_ctx->p_info->finalize_fn(p_context, p_digest, p_digest_size);
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hmac_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * p_digest,
+ size_t * const p_digest_size,
+ uint8_t const * p_key,
+ size_t key_size,
+ uint8_t const * p_data,
+ size_t data_size)
+{
+ ret_code_t err_code;
+ nrf_crypto_hmac_context_t * p_ctx;
+ void * p_allocated_context = NULL;
+
+ // Validate input. Only validate input parameters that are used locally, others are validated
+ // in the init, update and/or finalize functions.
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Allocate context if needed (not provided by the user).
+ if (p_context == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = (nrf_crypto_hmac_context_t *)p_allocated_context;
+ }
+ else
+ {
+ p_ctx = (nrf_crypto_hmac_context_t *)p_context;
+ }
+
+ // Perform integrated HMAC calculation by caling the frontend functions defined in this file
+ err_code = nrf_crypto_hmac_init(p_ctx, p_info, p_key, key_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ err_code = nrf_crypto_hmac_update(p_ctx, p_data, data_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ err_code = nrf_crypto_hmac_finalize(p_ctx, p_digest, p_digest_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ // Free context if allocated internally
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h
new file mode 100644
index 0000000..3a0340f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h
@@ -0,0 +1,226 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HMAC_H__
+#define NRF_CRYPTO_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hmac Hash-based message authentication code (HMAC) related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides functions to generate Hash-based message authentication code (HMAC).
+ *
+ * @details Provides functions to generate Hash-based message authentication code (HMAC) using
+ * one of the supported hash algorithms. This layer is independent of backend crypto library.
+ */
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_hmac_backend.h"
+#include "nrf_crypto_hmac_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Information structures used to select the specific algorithm (SHA-256)
+ *
+ * @details The information structure is used in a generic way but is populated by the backend,
+ * and contains backend specific data. */
+extern const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info;
+
+
+/**
+ * @brief Information structures used to select the specific algorithm (SHA-512)
+ *
+ * @details The information structure is used in a generic way but is populated by the backend,
+ * and contains backend specific data.
+ */
+extern const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info;
+
+
+/**
+ * @brief Context type for HMAC.
+ *
+ * @note The size of this type is scaled for the largest HMAC backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_hmac_context_t nrf_crypto_hmac_context_t;
+
+/**
+ * @brief Initialize context object for HMAC
+ *
+ * @details Use to initialize a context once it has been allocated.
+ *
+ * @note Must be called before @ref nrf_crypto_hmac_update. Can also be called after
+ * @ref nrf_crypto_hmac_finalize order to start a new HMAC calculation re-using an
+ * existing context object.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in] p_info Pointer to static info structure. This defines the algorithm.
+ * This should be either @ref g_nrf_crypto_hmac_sha256_info or
+ * @ref g_nrf_crypto_hmac_sha512_info.
+ * @param[in] p_key HMAC key.
+ * @param[in] key_size Length of the HMAC key in bytes.
+ *
+ * @retval NRF_SUCCESS Data successfully consumed.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL If p_context has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_info or p_key was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If key_size was invalid.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM (CC310 only).
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun
+ * the cryptographic routine at a later time.
+ * CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_init(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t const * p_key,
+ size_t key_size);
+
+
+/**
+ * @brief Feed data to HMAC algorithm.
+ *
+ * @note Must be called after @ref nrf_crypto_hmac_init and before @ref nrf_crypto_hmac_finalize.
+ * Can be called repeatedly to consume data as it arrives.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[in] p_data Pointer to input data buffer.
+ * @param[in] data_size Length of input data.
+ *
+ * @retval NRF_SUCCESS Data successfully consumed.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL If p_context has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED If p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If size was invalid.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM (CC310 only).
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun
+ * the cryptographic routine at a later time.
+ * CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_update(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size);
+
+
+/**
+ * @brief Calculate HMAC
+ *
+ * @note @ref nrf_crypto_hmac_update must be called at least once before calling this.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[out] p_digest Pointer to HMAC digest (result) buffer. Must be large enough to
+ * hold the digest (32 byte for SHA-256 and 64 byte for SHA-512).
+ * @param[in,out] p_digest_size Length of buffer as input. Length of digest as output.
+ *
+ * @retval NRF_SUCCESS HMAC hash was successfully calculated.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL If p_context was NULL.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED If p_context has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL If p_digest was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH If p_size is not enough to hold the digest.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun
+ * the cryptographic routine at a later time.
+ * CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_finalize(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+
+/**
+ * @brief Integrated HMAC wrapper function
+ *
+ * @note This is an integrated wrapper functions that can be used instead of calling other HMAC
+ * functions individually.
+ *
+ * @param[in,out] p_context Optional pointer to context structure.
+ * Context memory will be allocated internally if the pointer is NULL.
+ * @param[in] p_info Pointer to static info structure. This defines the algorithm.
+ * This should be either @ref g_nrf_crypto_hmac_sha256_info or
+ * @ref g_nrf_crypto_hmac_sha512_info.
+ * @param[out] p_digest Pointer to HMAC digest.
+ * Buffer must be large enough to hold the digest.
+ * @param[in,out] p_digest_size Length of digest (result) buffer as input.
+ * Length of digest as output.
+ * @param[in] p_key Pointer to HMAC key.
+ * @param[in] key_size Lenth of the HMAC key in bytes.
+ * @param[in] p_data Pointer to input data.
+ * @param[in] data_size Length of input data.
+ *
+ * @retval NRF_SUCCESS HMAC hash was successfully calculated.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_key or p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM (CC310 only).
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If key_size or data_size was invalid.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL If data_size was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH If data_size is not enough to hold the digest.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time. CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * p_digest,
+ size_t * const p_digest_size,
+ uint8_t const * p_key,
+ size_t key_size,
+ uint8_t const * p_data,
+ size_t data_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // #ifndef NRF_CRYPTO_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h
new file mode 100644
index 0000000..4547a8d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HMAC_BACKEND_H__
+#define NRF_CRYPTO_HMAC_BACKEND_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hmac_backend Meta backend.
+ * @{
+ * @ingroup nrf_crypto_hmac
+ *
+ * @brief Includes all backends definitions.
+ *
+ * @details This file includes all backend definitions, and provide a dummy context in case no
+ * backend is enabled. This is needed so that any project including HMAC headers will still
+ * compile when HMAC is not used/enabled.
+ */
+
+#include "sdk_common.h"
+#include "nrf_crypto_hmac_shared.h"
+#include "mbedtls_backend_hmac.h"
+#include "cc310_backend_hmac.h"
+#include "oberon_backend_hmac.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef NRF_CRYPTO_HMAC_SHA256_ENABLED
+// /** @internal @brief Fallback context type for HMAC SHA256 in case no backend is selected. */
+typedef nrf_crypto_hmac_internal_context_t nrf_crypto_backend_hmac_sha256_context_t;
+#endif // #ifndef NRF_CRYPTO_HMAC_SHA256_ENABLED
+
+#ifndef NRF_CRYPTO_HMAC_SHA512_ENABLED
+/** @internal @brief Fallback context type for HMAC SHA512 in case no backend is selected. */
+typedef nrf_crypto_hmac_internal_context_t nrf_crypto_backend_hmac_sha512_context_t;
+#endif // #ifndef NRF_CRYPTO_HMAC_SHA512_ENABLED
+
+
+/** @internal @brief Union holding a HMAC context. */
+typedef union
+{
+ nrf_crypto_backend_hmac_sha256_context_t hmac_sha256_context; /**< @brief Holds context for HMAC SHA-256. */
+ nrf_crypto_backend_hmac_sha512_context_t hmac_sha512_context; /**< @brief Holds context for HMAC SHA-512. */
+} nrf_crypto_backend_hmac_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_HMAC_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h
new file mode 100644
index 0000000..c8527f6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HMAC_SHARED_H__
+#define NRF_CRYPTO_HMAC_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hmac_shared Types shared between all @ref nrf_crypto_hmac backends.
+ * @{
+ * @ingroup nrf_crypto_hmac
+ *
+ * @brief Types shared between all @ref nrf_crypto_hmac backends.
+ *
+ * @details These types should not be used directly by the application.
+ */
+
+#include <stdint.h>
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @internal @brief HMAC algorithm type.
+ */
+typedef enum {
+ NRF_CRYPTO_HMAC_SHA256_TYPE, //!< HMAC using hash algorithm SHA256
+ NRF_CRYPTO_HMAC_SHA512_TYPE, //!< HMAC using hash algorithm SHA512
+} nrf_crypto_hmac_type_t;
+
+
+/**
+ * @internal @brief Function pointer type for HMAC backend init function.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_hmac_init instead.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[in] p_key HMAC key.
+ * @param[in] key_size Length of the HMAC key in bytes.
+*/
+typedef ret_code_t (*nrf_crypto_hmac_init_fn_t)(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size);
+
+
+/**
+ * @internal @brief Function pointer type for HMAC backend update function.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_hmac_update instead.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[in] p_data Pointer to input data buffer.
+ * @param[in] size Length of input data.
+*/
+typedef ret_code_t (*nrf_crypto_hmac_update_fn_t)(void * const p_context,
+ uint8_t const * p_data,
+ size_t size);
+
+
+/**
+ * @internal @brief Function pointer type for HMAC backend finalize function.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_hmac_finalize instead.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[out] p_digest HMAC digest (result) buffer.
+ * @param[in,out] p_size Length of buffer as input. Length of digest as output.
+*/
+typedef ret_code_t (*nrf_crypto_hmac_finalize_fn_t)(void * const p_context,
+ uint8_t * const p_digest,
+ size_t * p_size);
+
+
+/**
+ * @internal @brief structure holding the configuration of each particular algorithm.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_init_fn_t const init_fn; //!< Pointer to update function for specific backend.
+ nrf_crypto_hmac_update_fn_t const update_fn; //!< Pointer to update function for specific backend.
+ nrf_crypto_hmac_finalize_fn_t const finalize_fn; //!< Pointer to finalize function for specific backend.
+ size_t const digest_size; //!< Size of the digest of the HMAC operation.
+ size_t const context_size; //!< Size of the context type.
+ nrf_crypto_hmac_type_t const type; //!< HMAC algorithm type.
+} nrf_crypto_hmac_info_t;
+
+
+/**
+ * @internal @brief Common header for each HMAC context structures
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value; //!< Contains NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE if it is correctly initialized.
+ nrf_crypto_hmac_info_t const * p_info; //!< Points to information object related to selected algorithm.
+} nrf_crypto_hmac_internal_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_HMAC_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c
new file mode 100644
index 0000000..f86d5e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_init.h"
+#include "nrf_section.h"
+
+
+// Create a named section for crypto backend data
+NRF_SECTION_DEF(crypto_data, const nrf_crypto_backend_info_t);
+
+
+#define NRF_CRYPTO_BACKEND_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(crypto_data, nrf_crypto_backend_info_t, (i))
+#define NRF_CRYPTO_BACKEND_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(crypto_data, nrf_crypto_backend_info_t)
+
+typedef enum
+{
+ UNINITIALIZED,
+ INITIALIZING,
+ INITIALIZED,
+} nrf_crypto_state_t;
+
+static volatile nrf_crypto_state_t m_state = UNINITIALIZED;
+
+
+ret_code_t nrf_crypto_init(void)
+{
+ ret_code_t ret_val;
+ size_t const num_backends = NRF_CRYPTO_BACKEND_SECTION_ITEM_COUNT;
+
+ m_state = INITIALIZING;
+
+ // Iterate through each backends to call the init function
+ for (size_t i = 0; i < num_backends; i++)
+ {
+ nrf_crypto_backend_info_t const * p_backend = NRF_CRYPTO_BACKEND_SECTION_ITEM_GET(i);
+ ret_val = p_backend->init_fn();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+ }
+
+ // Set nrf_crypto to initialized
+ m_state = INITIALIZED;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_uninit(void)
+{
+ ret_code_t ret_val;
+ size_t const num_backends = NRF_CRYPTO_BACKEND_SECTION_ITEM_COUNT;
+
+ // Iterate through each backends to call the uninit function
+ for (size_t i = 0; i < num_backends; i++)
+ {
+ nrf_crypto_backend_info_t const * p_backend = NRF_CRYPTO_BACKEND_SECTION_ITEM_GET(i);
+ ret_val = p_backend->uninit_fn();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+ }
+
+ // Set nrf_crypto to uninitialized
+ m_state = UNINITIALIZED;
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_crypto_is_initialized(void)
+{
+ return (m_state == INITIALIZED);
+}
+
+
+bool nrf_crypto_is_initializing(void)
+{
+ return ((m_state == INITIALIZED) || m_state == INITIALIZING);
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h
new file mode 100644
index 0000000..a10fdde
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_INIT_H__
+#define NRF_CRYPTO_INIT_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_initialization Initialization
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Initialization related functions for nrf_crypto .
+ *
+ * @details @ref lib_crypto is responsible for global initialization of the nrf_crypto
+ * frontend and backends that are enabled in @ref sdk_config.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_section.h"
+#include "sdk_errors.h"
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@internal @brief Macro for registering a nrf_crypto backend for initialization by using
+ * nrf_section.
+ *
+ * @details This macro places a variable in a section named "crypto_data", which
+ * is initialized by @ref nrf_crypto_init.
+ *
+ * @note This macro is used internally based on sdk_config.h configurations for nrf_crypto
+ */
+#define CRYPTO_BACKEND_REGISTER(crypto_var) NRF_SECTION_ITEM_REGISTER(crypto_data, crypto_var)
+
+/**@internal @brief Type definition of function pointer to initialize the nrf_crypto backend.
+ *
+ * This function type is used internally. See @nrf_crypto_init for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_backend_init_fn_t)(void);
+
+
+/**@internal @brief Type definition of function pointer to uninitialize the nrf_crypto backend.
+ *
+ * This function type is used internally. Please see @nrf_crypto_uninit for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_backend_uninit_fn_t)(void);
+
+
+
+/**@internal @brief Type definition for structure holding the calling interface to
+ * init, uninit, enable, or disable an nrf_crypto_backend
+ *
+ * @note Some backends require no expressive init, uninit, enable, or disable.
+ * In this case, the backend will not use this structure type or only select
+ * to implement
+ */
+typedef struct
+{
+ nrf_crypto_backend_init_fn_t const init_fn;
+ nrf_crypto_backend_uninit_fn_t const uninit_fn;
+} nrf_crypto_backend_info_t;
+
+
+/**@brief Function for initializing nrf_crypto and all registered backends.
+ *
+ * @details Must always be called before any other @ref nrf_crypto function.
+ *
+ * @retval NRF_SUCCESS The initialization was successful.
+ * @retval NRF_ERROR_INTERNAL An internal error occured in the nrf_crypt backend init.
+ */
+ret_code_t nrf_crypto_init(void);
+
+
+/**@brief Function for uninitializing nrf_crypto and all registered backends.
+ *
+ * @retval NRF_SUCCESS If unititialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypt backend init.
+ */
+ret_code_t nrf_crypto_uninit(void);
+
+
+/**@brief Function reporting if nrf_crypto has been initialized.
+ *
+ * @retval True If cryptographic library is initialized.
+ * @retval False If cryptographic library is not initialized.
+ */
+bool nrf_crypto_is_initialized(void);
+
+
+/**@brief Function reporting if nrf_crypto is initialized or is in the process of being initialized.
+ *
+ * @retval True If cryptographic library is initializing or already initialized.
+ * @retval False If cryptographic library is not initialized.
+ */
+bool nrf_crypto_is_initializing(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_INIT_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h
new file mode 100644
index 0000000..0e2d163
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_MEM_H__
+#define NRF_CRYPTO_MEM_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mem Dynamic memory management module
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Module to manage dynamically allocated memory used by nrf_crypto APIs.
+ *
+ * @ref NRF_CRYPTO_ALLOCATOR definition is used to configure this module.
+ */
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "nrf_crypto_types.h"
+#include "sdk_alloca.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef __SDK_DOXYGEN__
+
+
+#define NRF_CRYPTO_ALLOCATOR_DEFAULT 0 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select default memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_USER 1 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select user defined memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_ALLOCA 2 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select stack based memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_MALLOC 3 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select stdlib's dynamic memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_NRF_MALLOC 4 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select mem_manager for memory allocation. */
+
+
+#ifndef NRF_CRYPTO_ALLOCATOR
+#define NRF_CRYPTO_ALLOCATOR NRF_CRYPTO_ALLOCATOR_DEFAULT
+#endif
+
+
+#if NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_DEFAULT
+#undef NRF_CRYPTO_ALLOCATOR
+#if SDK_ALLOCA_DEFINED && !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+#define NRF_CRYPTO_ALLOCATOR NRF_CRYPTO_ALLOCATOR_ALLOCA
+#else
+#define NRF_CRYPTO_ALLOCATOR NRF_CRYPTO_ALLOCATOR_NRF_MALLOC
+#endif
+#endif
+
+
+#if NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_USER
+
+#include "nrf_crypto_allocator.h"
+#ifndef NRF_CRYPTO_ALLOC
+#error "User defined allocator for nrf_crypto does not define NRF_CRYPTO_ALLOC"
+#endif
+#ifndef NRF_CRYPTO_FREE
+#error "User defined allocator for nrf_crypto does not define NRF_CRYPTO_FREE"
+#endif
+#ifndef NRF_CRYPTO_ALLOC_ON_STACK
+#error "User defined allocator for nrf_crypto does not define NRF_CRYPTO_ALLOC_ON_STACK"
+#endif
+
+#elif NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_ALLOCA
+
+#if !SDK_ALLOCA_DEFINED
+#warning "Stack based allocation is selected, but alloca() is not supported on this platform"
+#endif
+#define NRF_CRYPTO_ALLOC(size) (alloca((size_t)(size)))
+#define NRF_CRYPTO_FREE(p_buffer) // Empty
+#define NRF_CRYPTO_ALLOC_ON_STACK 1
+
+#elif NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_MALLOC
+
+#include "stdlib.h"
+#define NRF_CRYPTO_ALLOC(size) (malloc((size_t)(size)))
+#define NRF_CRYPTO_FREE(p_buffer) (free((void *)(p_buffer)))
+#define NRF_CRYPTO_ALLOC_ON_STACK 0
+
+#elif NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_NRF_MALLOC
+
+#include "mem_manager.h"
+#define NRF_CRYPTO_ALLOC(size) (nrf_malloc((uint32_t)(size)))
+#define NRF_CRYPTO_FREE(p_buffer) (nrf_free((void *)(p_buffer)))
+#define NRF_CRYPTO_ALLOC_ON_STACK 0
+
+#else
+
+#error "Invalid NRF_CRYPTO_ALLOCATOR configuration value"
+
+#endif
+
+
+#else // __SDK_DOXYGEN__
+
+
+/** @brief Defines memory allocation function for nrf_crypto.
+ *
+ * This macro is used internally by nrf_crypto library to allocate temporary memory. It is not
+ * intended to be used outside nrf_crypto library. How memory is actually allocated is configured
+ * by @ref NRF_CRYPTO_ALLOCATOR definition.
+ *
+ * If user macros are selected by @ref NRF_CRYPTO_ALLOCATOR then this macro have to be defined by
+ * the user in "nrf_crypto_allocator.h" file. The file will be included into "nrf_crypto_mem.h".
+ *
+ * If @ref NRF_CRYPTO_ALLOC_ON_STACK is 1 then this function will allocate data on stack,
+ * so make sure that returned pointer is not used outside the caller function.
+ *
+ * @param size Number of bytes to allocate.
+ * @returns Pointer to newly allocated memory or NULL on error.
+ */
+#define NRF_CRYPTO_ALLOC(size)
+
+/** @brief Defines memory deallocation function for nrf_crypto.
+ *
+ * This macro is used internally by nrf_crypto library to deallocate temporary memory. It is not
+ * intended to be used outside nrf_crypto library.
+ *
+ * If user macros are selected by @ref NRF_CRYPTO_ALLOCATOR then this macro have to be defined by
+ * the user in "nrf_crypto_allocator.h" file. The file will be included into "nrf_crypto_mem.h".
+ *
+ * @param p_buffer Pointer to memory buffer for deallocation.
+ */
+#define NRF_CRYPTO_FREE(p_buffer)
+
+/** @brief Contains 1 if memory allocated by @ref NRF_CRYPTO_ALLOC is on stack or 0 otherwise.
+ *
+ * This definition is used internally by nrf_crypto library. It is not intended to be used outside
+ * nrf_crypto library.
+ *
+ * If user macros are selected by @ref NRF_CRYPTO_ALLOCATOR then this macro have to be defined by
+ * the user in "nrf_crypto_allocator.h" file. The file will be included into "nrf_crypto_mem.h".
+ */
+#define NRF_CRYPTO_ALLOC_ON_STACK
+
+
+#endif // __SDK_DOXYGEN__
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+ #endif // NRF_CRYPTO_MEM_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c
new file mode 100644
index 0000000..97532a5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c
@@ -0,0 +1,430 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_init.h"
+#include "nrf_log.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_rng_shared.h"
+#include "nrf_crypto_rng_backend.h"
+#include "nrf_stack_info.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+#define NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE (0x4be57265)
+
+static nrf_crypto_backend_rng_context_t * mp_allocated_context = NULL;
+static nrf_crypto_backend_rng_context_t * mp_context = NULL;
+static uint32_t m_initialized = 0;
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+static nrf_crypto_backend_rng_context_t m_context;
+static nrf_crypto_rng_temp_buffer_t m_temp_buffer;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+
+static bool is_vector_greater_or_equal(uint8_t const * const p_vector,
+ uint8_t const * const p_min,
+ size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ {
+ if (p_vector[i] != p_min[i])
+ {
+ if (p_vector[i] > p_min[i])
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+// Return true if value p_vector is between (including) p_min and p_max.
+static bool is_vector_in_range(uint8_t const * const p_vector,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size)
+{
+ if (!is_vector_greater_or_equal(p_vector, p_min, size))
+ {
+ return false;
+ }
+
+ if (!is_vector_greater_or_equal(p_max, p_vector, size))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+static uint32_t count_leading_zeros(uint8_t const * const p_vector, size_t size)
+{
+ uint32_t leading_zeros = 0;
+ uint32_t nonzero_byte = 0xFF;
+
+ // Find leading all-zero elements.
+ for (uint32_t i = 0; i < size; i++)
+ {
+ if (p_vector[i] == 0)
+ {
+ leading_zeros += 8;
+ }
+ else
+ {
+ nonzero_byte = p_vector[i];
+ break;
+ }
+ }
+
+ // Find leading zeros in non-zero element.
+ for (uint32_t i = 0; i < 8; i++)
+ {
+ nonzero_byte <<= 1;
+
+ if ((nonzero_byte & ~0xff) > 0)
+ {
+ break;
+ }
+
+ leading_zeros ++;
+ }
+
+ return leading_zeros;
+}
+
+
+static ret_code_t generate(uint8_t * const p_target, size_t size, bool use_mutex)
+{
+ ret_code_t ret_code;
+
+ VERIFY_TRUE(p_target != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(size > 0, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ VERIFY_TRUE(m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ ret_code = nrf_crypto_rng_backend_vector_generate(mp_context, p_target, size, use_mutex);
+
+ // Reseed internally and try again if reseed is required by the backend.
+ // (CC310 only as mbed TLS handles reseeding internally.)
+ if (ret_code == NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED)
+ {
+ ret_code = nrf_crypto_rng_reseed(NULL, NULL, 0);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ ret_code = nrf_crypto_rng_backend_vector_generate(mp_context, p_target, size, use_mutex);
+ }
+
+ return ret_code;
+}
+
+
+static ret_code_t generate_in_range(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size,
+ bool use_mutex)
+{
+ uint32_t const max_leading_zeros = count_leading_zeros(p_max, size);
+ ret_code_t ret_code;
+
+ VERIFY_TRUE(p_target != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(size > 0, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+ VERIFY_TRUE(p_min != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_max != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(is_vector_greater_or_equal(p_max, p_min, size), NRF_ERROR_CRYPTO_INVALID_PARAM);
+
+ do
+ {
+ ret_code = nrf_crypto_rng_backend_vector_generate(mp_context, p_target, size, use_mutex);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ // Mask leading zeros in generated vector instead of always discarding a too large vectors.
+ memset(p_target, 0, max_leading_zeros / 8);
+ if ((max_leading_zeros & 0x07) > 0)
+ {
+ p_target[max_leading_zeros / 8] =
+ p_target[max_leading_zeros / 8] & (0xff >> (max_leading_zeros & 0x07));
+ }
+ } while (!is_vector_in_range(p_target, p_min, p_max, size));
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate(uint8_t * const p_target, size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate(p_target, size, true);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate_in_range(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate_in_range(p_target, p_min, p_max, size, true);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate_no_mutex(uint8_t * const p_target, size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate(p_target, size, false);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate_in_range_no_mutex(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate_in_range(p_target, p_min, p_max, size, false);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_init(nrf_crypto_rng_context_t * p_context,
+ nrf_crypto_rng_temp_buffer_t * p_temp_buffer)
+{
+ ret_code_t ret_code;
+ nrf_crypto_rng_temp_buffer_t * p_allocated_temp_buffer = NULL;
+
+ // Check if the stack has overflowed. This can typically happen if the application has put the
+ // ~6 kB large temp buffer for CC310 on the stack.
+ if (nrf_stack_info_overflowed())
+ {
+ NRF_LOG_ERROR("Stack overflow detected.");
+ return NRF_ERROR_CRYPTO_STACK_OVERFLOW;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_AUTO_INIT)
+ VERIFY_TRUE(nrf_crypto_is_initializing(), NRF_ERROR_CRYPTO_NOT_INITIALIZED);
+#else
+ VERIFY_TRUE(nrf_crypto_is_initialized(), NRF_ERROR_CRYPTO_NOT_INITIALIZED);
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_AUTO_INIT)
+
+ // Do nothing if RNG module is already initialized.
+ if (mp_context != 0 && (m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE))
+ {
+ return NRF_SUCCESS;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ VERIFY_TRUE(p_context == NULL, NRF_ERROR_CRYPTO_INVALID_PARAM);
+ VERIFY_TRUE(p_temp_buffer == NULL, NRF_ERROR_CRYPTO_INVALID_PARAM);
+
+ mp_context = &m_context;
+ p_temp_buffer = &m_temp_buffer;
+
+#else // !NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ if (p_context == NULL)
+ {
+ if (NRF_CRYPTO_ALLOC_ON_STACK)
+ {
+ NRF_LOG_ERROR("RNG context cannot be allocated on the stack.");
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ else
+ {
+ mp_allocated_context = NRF_CRYPTO_ALLOC(sizeof(nrf_crypto_backend_rng_context_t));
+ if (mp_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ mp_context = mp_allocated_context;
+ }
+ }
+ else
+ {
+ mp_context = p_context;
+ }
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ // Allocate temporary buffer internally if not statically allocated or provided by the user.
+ if (p_temp_buffer == NULL)
+ {
+ p_allocated_temp_buffer = NRF_CRYPTO_ALLOC(sizeof(nrf_crypto_rng_temp_buffer_t));
+
+ if (p_allocated_temp_buffer == NULL)
+ {
+ if (mp_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(mp_allocated_context);
+ }
+
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+
+ p_temp_buffer = p_allocated_temp_buffer;
+ }
+
+ ret_code = nrf_crypto_rng_backend_init(mp_context, p_temp_buffer);
+ if (ret_code == NRF_SUCCESS)
+ {
+ m_initialized = NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE;
+ mp_context->header.init_value = NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE;
+ }
+
+ if (p_allocated_temp_buffer != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_temp_buffer);
+ }
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_uninit(void)
+{
+ ret_code_t ret_code;
+
+ VERIFY_TRUE(m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ VERIFY_TRUE(mp_context->header.init_value == NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ mp_context->header.init_value = 0;
+ m_initialized = 0;
+
+ ret_code = nrf_crypto_rng_backend_uninit(mp_context);
+
+ if (mp_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(mp_allocated_context);
+ }
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_reseed(nrf_crypto_rng_temp_buffer_t * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ ret_code_t ret_code;
+ void * p_allocated_temp_buffer = NULL;
+
+ // Check if the stack has overflowed. This can typically happen if the application has put the
+ // ~6 kB large temp buffer for CC310 on the stack.
+ if (nrf_stack_info_overflowed())
+ {
+ NRF_LOG_ERROR("Stack overflow detected.");
+ return NRF_ERROR_CRYPTO_STACK_OVERFLOW;
+ }
+
+ if (size > 0)
+ {
+ VERIFY_TRUE(p_input_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ }
+
+ VERIFY_TRUE(m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ VERIFY_TRUE(p_temp_buffer == NULL, NRF_ERROR_CRYPTO_INVALID_PARAM);
+ p_temp_buffer = &m_temp_buffer;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ // Allocate temporary buffer internally if not statically allocated or provided by the user.
+ if (p_temp_buffer == NULL)
+ {
+ p_allocated_temp_buffer = NRF_CRYPTO_ALLOC(sizeof(nrf_crypto_rng_temp_buffer_t));
+ if (p_allocated_temp_buffer == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_temp_buffer = (nrf_crypto_rng_temp_buffer_t *)p_allocated_temp_buffer;
+ }
+
+ ret_code = nrf_crypto_rng_backend_reseed(mp_context, p_temp_buffer, p_input_data, size);
+
+ if (p_allocated_temp_buffer != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_temp_buffer);
+ }
+
+ return ret_code;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h
new file mode 100644
index 0000000..bb50218
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h
@@ -0,0 +1,285 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_RNG_H__
+#define NRF_CRYPTO_RNG_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_rng RNG related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief RNG related functions
+ *
+ * @details There are two available RNG backends:
+ * - ARM CryptoCell CC310 (default for devices with CC310).
+ * - nRF HW RNG peripheral.
+ * * CTR-DRBG mode - nRF HW RNG used for seeding mbed TLS CTR-DRBG (default for
+ * devices without CC310).
+ * * Raw mode - all data is generated by the nRF HW RNG.
+ *
+ * The CC310 backend meets the standards NIST 800-90B3 and AIS-31 (Class “P2 High”), and
+ * should be preferred in most cases on devices that includes the CC310 core. Devices that
+ * do not include CC310 should normally use the nRF HW RNG with mbed TLS CTR-DRBG. The
+ * mbed TLS CTR-DRBG code is standardized by NIST (SP 800-90A Rev. 1).
+ */
+
+#include "sdk_common.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_rng_shared.h"
+#include "nrf_crypto_rng_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Context type for RNG.
+ *
+ * @note The actual type depend on the backend in use.
+ */
+typedef nrf_crypto_backend_rng_context_t nrf_crypto_rng_context_t;
+
+
+/**
+ * @brief Temporary work buffer type for RNG.
+ *
+ * @details Only needed during initializing. Can be freed when @ref nrf_crypto_rng_init has
+ * returned. Not needed if @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config.
+ *
+ * @note The actual type depend on the backend in use.
+ */
+typedef nrf_crypto_backend_rng_temp_buffer_t nrf_crypto_rng_temp_buffer_t;
+
+
+/**@brief Initialize the random number generator.
+ *
+ * @details This function has no effect when @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is enabled.
+ *
+ * @warning The p_temp_buffer is 6112 bytes when using the CC310 backend. Ensure that stack size
+ * is sufficient if allocated on stack. Applications that use nRF HW RNG as backend or are
+ * not RAM constrained can use internal static allocation of context and temporary buffers
+ * (@ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED).
+ *
+ * @note The context object can be reused without the need for a full reinitialization of the
+ * backend in case of for example wakeup from system OFF, provided that the context is
+ * located in a memory block that is retained. This only apply to the CC310 backend, and when
+ * the context is allocated manually (NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED disabled).
+ *
+ * @param[in] p_context Pointer to context memory. The context will be managed
+ * internally, and the pointer is not used for subsequent calls to
+ * the nrf_crypto_rng API. The context memory is needed until
+ * @ref nrf_crypto_rng_uninit is called, so it should normally not
+ * be on the stack. Use NULL if
+ * @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config (recommended for most applications).
+ *
+ * @param[in,out] p_temp_buffer Temporary buffer needed during initialization of the backend. It
+ * is not used after the return of this function, and can be freed
+ * at that point. Buffer is allocated internally if the pointer is
+ * NULL, using the allocated defined by @ref NRF_CRYPTO_ALLOCATOR
+ * in @c sdk_config.h. Use NULL if
+ * @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config (recommended for most applications).
+ *
+ * @retval NRF_SUCCESS If random number generator was initialized
+ * successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to this
+ * function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL p_context was NULL.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the nrf_crypto
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context or work
+ * buffer.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_init(nrf_crypto_rng_context_t * p_context,
+ nrf_crypto_rng_temp_buffer_t * p_temp_buffer);
+
+
+/**@brief Uninitialize the random number generator.
+ *
+ * @retval NRF_SUCCESS If RNG was uninitialized successfully.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED RNG has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * nrf_crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_uninit(void);
+
+
+/**@brief Generate random data of given size.
+ *
+ * @details @ref nrf_crypto_rng_init must be called prior to this function unless
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is enabled in @ref sdk_config.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] size Length (in bytes) to generate random data for.
+ *
+ * @retval NRF_SUCCESS Data was generated successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED @ref nrf_crypto_rng_init was not called
+ * prior to this function and
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is
+ * disabled.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_target was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH Size was 0 or larger than the backend
+ * supports.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected in
+ * @ref nrf_crypto_rng_init when using auto
+ * initialization. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_vector_generate(uint8_t * const p_target, size_t size);
+
+
+/**@brief Generate a vector of constrained random data of given size, between the specified min
+ * and max values.
+ *
+ * @details @ref nrf_crypto_rng_init must be called prior to this function unless
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is enabled in @ref sdk_config.
+ *
+ * All vectors are in big-endian format, with the most significant byte as the first
+ * element / lowest address.
+ *
+ * @note This function may execute for a long time if the window between p_min and p_max is small.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] p_min Byte array defining the lower limit of the random vector.
+ * @param[in] p_max Byte array defining the upper limit of the random vector.
+ * @param[in] size Length (in bytes) to generate random data for. Note that all three
+ * buffers (p_target, p_min and p_max) must be of this size.
+ *
+ * @retval NRF_SUCCESS Data was generated successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED @ref nrf_crypto_rng_init was not called
+ * prior to this function and
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is
+ * disabled.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_target was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_min or p_max was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH Size was 0 or larger than the backend
+ * supports.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected in
+ * @ref nrf_crypto_rng_init when using auto
+ * initialization. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_vector_generate_in_range(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size);
+
+
+/**
+ * @brief This function is used for reseeding the RNG with additional entropy.
+ *
+ * @details The backends will reseed automatically when required. This function can be used to
+ * reseed at specific times and to provide additional data that is used to add personalized
+ * randomness.
+ *
+ * @note Reseeding is not supported if using the nRF HW RNG backend without mbed TLS CTR-DRBG
+ * (NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED disabled in sdk_config.h).
+ *
+ * @warning The p_temp_buffer is 6112 bytes when the CC310 backend is used. Ensure that stack size
+ * is sufficient if allocated on stack.
+ *
+ * @param[in,out] p_temp_buffer Temporary buffer needed during reseeding. It
+ * is not used after the return of this function, and can be freed
+ * at that point. Buffer is allocated internally if the pointer is
+ * NULL, using the allocated defined by @ref NRF_CRYPTO_ALLOCATOR
+ * in @c sdk_config.h. Use NULL if
+ * @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config (recommended for most applications).
+ * @param[in] p_input_data Optional input data used to increase the entropy.
+ * @param[in] size Length of input data. Must be 0, 4, 8 or 12 for CC310.
+ *
+ * @retval NRF_SUCCESS Data was generated successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED @ref nrf_crypto_rng_init was not called
+ * prior to this function and
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is
+ * disabled.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_temp_buffer was NULL or p_input_data was
+ * NULL and size > 0 .
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH Invalid input data size.
+ * @retval NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE Reseeding not supported by backend.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_reseed(nrf_crypto_rng_temp_buffer_t * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_RNG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h
new file mode 100644
index 0000000..0fd900f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_RNG_BACKEND_H__
+#define NRF_CRYPTO_RNG_BACKEND_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_rng_backend Meta RNG backend.
+ * @{
+ * @ingroup nrf_crypto_rng
+ *
+ * @brief Includes all backends definitions.
+ *
+ * @details This file includes all backend definitions.
+ */
+
+#include "cc310_backend_rng.h"
+#include "nrf_hw_backend_rng.h"
+#include "nrf_hw_backend_rng_mbedtls.h"
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @internal @brief Fallback dummy context type in case no backend is selected */
+typedef nrf_crypto_rng_internal_context_t nrf_crypto_backend_rng_context_t;
+
+/** @internal @brief Fallback dummy temp buffer type in case no backend is selected . */
+typedef struct
+{
+ uint32_t reserved;
+} nrf_crypto_backend_rng_temp_buffer_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+/**@} */
+
+#endif // NRF_CRYPTO_RNG_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h
new file mode 100644
index 0000000..bbf7fd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_RNG_SHARED_H__
+#define NRF_CRYPTO_RNG_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_rng_shared Types shared between all @ref nrf_crypto_rng backends.
+ * @{
+ * @ingroup nrf_crypto_rng
+ *
+ * @brief Types shared between all @ref nrf_crypto_rng backends.
+ *
+ * @details These types should not be used directly by the application.
+ */
+
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE (0x4d616961)
+
+
+/**
+ * @internal @brief Common header for each RNG backend context.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value; //!< Contains NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE if initialized.
+} nrf_crypto_rng_internal_context_t;
+
+
+/**
+ * @internal @brief Function for initializing the RNG backend.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_init instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in,out] p_temp_buffer Temporary buffer needed during initialization of the backend.
+ * @param[in] use_mutex Use mutex to prevent simultanious usage of backend resources.
+ */
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context,
+ void * const p_temp_buffer);
+
+
+/**
+ * @internal @brief Function for uninitializing the RNG backend.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_uninit instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in] use_mutex Use mutex to prevent simultanious usage of backend resources.
+ */
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context);
+
+
+/**
+ * @internal @brief Function for retrieving a random vector from the RNG backend.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_vector_generate instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[out] p_target Buffer to hold the random generated data.
+ * @param[in] size Length (in bytes) to generate random data for.
+ * @param[in] use_mutex Use mutex to prevent simultanious usage of backend resources.
+ */
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex);
+
+
+/**
+ * @internal @brief This function is used for reseeding the RNG with additional entropy.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_reseed instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in,out] p_temp_buffer Temporary buffer needed during initialization of the backend.
+ * @param[in] p_input_data Input data used to increase the entropy.
+ * @param[in] size Length of input data.
+ */
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_RNG_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c
new file mode 100644
index 0000000..689ee48
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_crypto_shared.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+
+void nrf_crypto_internal_swap_endian_in_place(uint8_t * p_buffer, size_t size)
+{
+ ASSERT(p_buffer != NULL);
+
+ uint8_t temp;
+ uint8_t * p_first = p_buffer;
+ uint8_t * p_last = p_buffer + size - 1;
+ while (p_last >= p_first)
+ {
+ temp = *p_first;
+ *p_first = *p_last;
+ *p_last = temp;
+ p_first++;
+ p_last--;
+ }
+}
+
+
+void nrf_crypto_internal_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t size)
+{
+ ASSERT(p_out != NULL);
+ ASSERT(p_in != NULL);
+
+ uint8_t const * p_first = p_in;
+ uint8_t * p_last = p_out + size - 1;
+ while (p_last >= p_out)
+ {
+ *p_last = *p_first;
+ p_first++;
+ p_last--;
+ }
+}
+
+
+void nrf_crypto_internal_double_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t part_size)
+{
+ nrf_crypto_internal_swap_endian(p_out, p_in, part_size);
+ nrf_crypto_internal_swap_endian(&p_out[part_size], &p_in[part_size], part_size);
+}
+
+
+void nrf_crypto_internal_double_swap_endian_in_place(uint8_t * p_buffer, size_t part_size)
+{
+ nrf_crypto_internal_swap_endian_in_place(p_buffer, part_size);
+ nrf_crypto_internal_swap_endian_in_place(&p_buffer[part_size], part_size);
+}
+
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h
new file mode 100644
index 0000000..3e6dae3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_SHARED_H__
+#define NRF_CRYPTO_SHARED_H__
+
+/** @internal @file
+ *
+ * @defgroup nrf_crypto_shared Shared macros for nrf_crypto
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Module containing shared macros for nrf_crypto.
+ */
+
+#include "sdk_macros.h"
+#include "nrf_crypto_mem.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @internal @brief Macro for verifying statement to be true. It will cause the exterior function
+ * to return err_code if the statement is not true, but only after freeing the
+ * memory pointed to by p_memory if p_memory is not NULL.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ * @param[in] p_memory The memory block to be freed in case of error.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is false.
+ */
+#define NRF_CRYPTO_VERIFY_TRUE_DEALLOCATE(statement, err_code, p_memory) \
+do \
+{ \
+ if (!(statement)) \
+ { \
+ if (p_memory != NULL) \
+ { \
+ NRF_CRYPTO_FREE(p_memory); \
+ } \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**
+ * @internal @brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the
+ * exterior function to return err_code if the err_code is not @ref NRF_SUCCESS,
+ * but only after freeing the memory pointed to by p_memory if p_memory is not
+ * NULL.
+ *
+ * @param[in] err_code The error code to check.
+ * @param[in] p_memory The memory block to be freed in case of error.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE()
+#else
+#define NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_memory) \
+ NRF_CRYPTO_VERIFY_TRUE_DEALLOCATE((err_code) == NRF_SUCCESS, (err_code), p_memory)
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**
+ * @internal @brief Generate a vector with random data of given size.
+ *
+ * @details This function does not check or lock the CC310 mutex, and should only be used
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] size Length (in bytes) to generate random data for.
+ *
+ * @retval See return values for @ref nrf_crypto_rng_vector_generate.
+ */
+ret_code_t nrf_crypto_rng_vector_generate_no_mutex(uint8_t * const p_target, size_t size);
+
+
+/**
+ * @internal @brief Generate a vector of constrained random data of given size, between the
+ * specified min and max values.
+ *
+ * @details This function does not check or lock the CC310 mutex, and should only be used
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] p_min Byte array defining the lower limit of the random vector.
+ * @param[in] p_max Byte array defining the upper limit of the random vector.
+ * @param[in] size Length (in bytes) to generate random data for. Note that all three
+ * buffers (p_target, p_min and p_max) must be of this size.
+ *
+ * @retval See return values for @ref nrf_crypto_rng_vector_generate_in_range.
+ */
+ret_code_t nrf_crypto_rng_vector_generate_in_range_no_mutex(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size);
+
+
+/** @internal @brief Swap bytes order inside provided buffer (in place).
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_buffer Buffer with data to swap.
+ * @param[in] size Number of bytes in @p p_buffer.
+ */
+void nrf_crypto_internal_swap_endian_in_place(uint8_t * p_buffer, size_t size);
+
+
+/** @internal @brief Copy from one buffer to another and swap byte order.
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[out] p_out Buffer with source data.
+ * @param[in] p_in Destination buffer with swapped bytes.
+ * @param[in] size Number of bytes in @p p_out and @p p_in.
+ */
+void nrf_crypto_internal_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t size);
+
+
+/** @internal @brief Swap bytes order inside buffer containing two integers (in place).
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_buffer Buffer with data to swap.
+ * @param[in] part_size Number of bytes in single integer which is half of size of @p p_buffer.
+ */
+void nrf_crypto_internal_double_swap_endian_in_place(uint8_t * p_buffer, size_t part_size);
+
+
+/** @internal @brief Copy from one buffer containing two integers to another and swap byte order of each integer.
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[out] p_out Buffer with source data.
+ * @param[in] p_in Destination buffer with swapped bytes.
+ * @param[in] part_size Number of bytes in single integer which is half of size of @p p_out and @p p_in.
+ */
+void nrf_crypto_internal_double_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t part_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c
new file mode 100644
index 0000000..c80f141
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_svc_function.h"
+#include "nrf_error.h"
+#include "sdk_common.h"
+
+/* use direct calls */
+#define SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION
+#include "nrf_crypto.h"
+
+#ifndef NRF51
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_init) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_INIT,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_init
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_public_key_compute) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_PUBLIC_KEY_COMPUTE,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_public_key_compute
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_shared_secret_compute) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_SHARED_SECRET_COMPUTE,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_shared_secret_compute
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_sign) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_SIGN,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_sign
+};
+
+#endif // #ifndef NRF51
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_verify) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_VERIFY,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_verify
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_hash_compute) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_HASH_COMPUTE,
+ .func_ptr = &nrf_crypto_hash_compute
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h
new file mode 100644
index 0000000..9d428b1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_CRYPTO_TYPES_H__
+#define NRF_CRYPTO_TYPES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_types Commonly shared types
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides definitions of commonly shared cryptographic types like hashes and curves used in the nrf_crypto APIs.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Hashing algorithms that are available through nrf_crypto.
+ *
+ * @note All cryptographic hash types may not be available through the nrf_crypto backend.
+ */
+typedef enum
+{
+ NRF_CRYPTO_HASH_TYPE_INVALID = 0x00, //!< Invalid hashing algorithm.
+ NRF_CRYPTO_HASH_TYPE_MD5 = 0x01, //!< MD5.
+ NRF_CRYPTO_HASH_TYPE_SHA1 = 0x03, //!< SHA-1.
+ NRF_CRYPTO_HASH_TYPE_SHA224 = 0x04, //!< SHA-224 (SHA-2).
+ NRF_CRYPTO_HASH_TYPE_SHA256 = 0x05, //!< SHA-256 (SHA-2).
+ NRF_CRYPTO_HASH_TYPE_SHA384 = 0x06, //!< SHA-384 (SHA-2).
+ NRF_CRYPTO_HASH_TYPE_SHA512 = 0x07, //!< SHA-512 (SHA-2).
+
+} nrf_hash_type_t;
+
+/**@defgroup NRF_CRYPTO_HASH_SIZES Cryptographic hash sizes
+ * @brief Sizes of different cryptographic hashes.
+ * @{ */
+#define NRF_CRYPTO_HASH_SIZE_MD5 (20)
+#define NRF_CRYPTO_HASH_SIZE_SHA1 (20)
+#define NRF_CRYPTO_HASH_SIZE_SHA224 (28)
+#define NRF_CRYPTO_HASH_SIZE_SHA256 (32)
+#define NRF_CRYPTO_HASH_SIZE_SHA384 (48)
+#define NRF_CRYPTO_HASH_SIZE_SHA512 (64)
+/** @} */
+
+
+/**@brief Type definition for key size.
+ */
+typedef enum
+{
+ NRF_CRYPTO_KEY_SIZE_128 = 128,
+ NRF_CRYPTO_KEY_SIZE_192 = 192,
+ NRF_CRYPTO_KEY_SIZE_256 = 256
+} nrf_crypto_key_size_id_t;
+
+/**@brief Type specifying whether decrypt or encrypt operation shall be performed.
+ */
+typedef enum
+{
+ NRF_CRYPTO_DECRYPT = 0,
+ NRF_CRYPTO_ENCRYPT = 1,
+ NRF_CRYPTO_MAC_CALCULATE = 2
+} nrf_crypto_operation_t;
+
+#define NRF_CRYPTO_AES_BLOCK_SIZE (16u) // 16 bytes
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // #ifndef NRF_CRYPTO_TYPES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c
new file mode 100644
index 0000000..d2b2d6d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c
@@ -0,0 +1,662 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CSENSE)
+
+#include <string.h>
+
+#include <nrfx.h>
+#include "nrf_csense.h"
+#include "nrf_peripherals.h"
+#include "nrf_assert.h"
+
+#if defined(__CC_ARM)
+#elif defined(__ICCARM__)
+#elif defined(__GNUC__)
+ #ifndef __CLZ
+ #define __CLZ(x) __builtin_clz(x)
+ #endif
+#endif
+
+APP_TIMER_DEF(nrf_csense_timer);
+
+typedef struct
+{
+ nrf_csense_event_handler_t event_handler; //!< Event handler for module.
+ nrfx_drv_state_t state; //!< State of module.
+ uint32_t ticks; //!< Timeout ticks of app_timer instance controlling csense module.
+ uint16_t raw_analog_values[MAX_ANALOG_INPUTS]; //!< Raw values of measurements.
+ uint8_t enabled_analog_channels_mask; //!< Mask of enabled channels.
+} nrf_csense_t;
+
+/* Module instance. */
+static nrf_csense_t m_nrf_csense;
+
+/* First of touch elements instances that creates linked list. */
+static nrf_csense_instance_t * mp_nrf_csense_instance_head;
+
+/* Buffer for values got from measurements. */
+static uint16_t m_values_buffer[NRF_CSENSE_MAX_PADS_NUMBER];
+
+/**
+ * @brief Function for handling time-outs.
+ *
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ */
+static void csense_timer_handler(void * p_context)
+{
+ if (m_nrf_csense.state != NRFX_DRV_STATE_POWERED_ON)
+ {
+ return;
+ }
+
+ if (nrf_drv_csense_sample() == NRF_ERROR_BUSY)
+ {
+ return;
+ }
+}
+
+
+/**
+ * @brief Function for updating maximum or minimum value.
+ *
+ * @param [in] p_instance Pointer to csense instance.
+ * @param [in] p_pad Pointer to pad which should be checked for minimum or maximum value.
+ */
+__STATIC_INLINE void min_or_max_update(nrf_csense_instance_t const * p_instance,
+ nrf_csense_pad_t * p_pad)
+{
+ uint16_t val = m_nrf_csense.raw_analog_values[p_pad->analog_input_number];
+
+ if (p_instance->min_max[p_pad->pad_index].min_value > val)
+ {
+ p_instance->min_max[p_pad->pad_index].min_value = val;
+ }
+
+ if (p_instance->min_max[p_pad->pad_index].max_value < val)
+ {
+ p_instance->min_max[p_pad->pad_index].max_value = val;
+ }
+}
+
+
+/**
+ * @brief Function for calculating proportions on slider pad.
+ *
+ * @note This function help to self calibrate the pads.
+ *
+ * @param [in] p_instance Pointer to csense instance.
+ * @param [in] p_pad Pointer to pad to calculate ratio for.
+ *
+ * @return Difference between maximum and minimum values read on pads or 0 if minimum is bigger than maximum.
+ *
+ */
+__STATIC_INLINE uint16_t ratio_calculate(nrf_csense_instance_t const * p_instance,
+ nrf_csense_pad_t * p_pad)
+{
+ if (p_instance->min_max[p_pad->pad_index].max_value > p_instance->min_max[p_pad->pad_index].min_value)
+ {
+ uint16_t scale;
+ scale = (uint16_t)(p_instance->min_max[p_pad->pad_index].max_value -
+ p_instance->min_max[p_pad->pad_index].min_value);
+ return scale;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+/**
+ * @brief Function for calculating step.
+ *
+ * Function calculates step for slider basing on index of touched pads and values measured on
+ * them and neighboring pads.
+ *
+ * @param[in] p_instance Pointer to csense instance.
+ * @param[in] pad_index Index of the pad.
+ *
+ * @return Detected touched step.
+ */
+static uint16_t calculate_step(nrf_csense_instance_t * p_instance,
+ uint8_t pad_index)
+{
+ uint16_t step = 0;
+ uint32_t values_sum;
+ uint32_t values_product;
+
+ pad_index += 1;
+
+ values_sum = m_values_buffer[pad_index] + m_values_buffer[pad_index - 1] +
+ m_values_buffer[pad_index + 1];
+ values_product = (uint32_t)(p_instance->steps-1) *
+ (m_values_buffer[pad_index - 1] * (pad_index - 2)
+ + m_values_buffer[pad_index] * (pad_index - 1)
+ + m_values_buffer[pad_index + 1] * (pad_index));
+ step = 1 + ROUNDED_DIV(values_product, (values_sum * (p_instance->number_of_pads - 1))); // Add 1 to the result of the division
+ // to get the appropriate range of values.
+ memset((void*)m_values_buffer, 0, sizeof(m_values_buffer));
+
+ return step;
+}
+
+
+/**
+ * @brief Function for finding mask of touched pads.
+ *
+ * @param [in] p_instance Pointer to csense instance.
+ *
+ * @return Mask of touched pads.
+ */
+static uint32_t find_touched_mask(nrf_csense_instance_t const * p_instance)
+{
+ uint32_t touched_mask = 0;
+ uint16_t max_value = 0;
+ uint16_t ratio;
+ nrf_csense_pad_t * p_pad;
+
+ for (p_pad = p_instance->p_nrf_csense_pad; NULL != p_pad; p_pad = p_pad->p_next_pad) // run through all pads and look for those with biggest value
+ {
+ min_or_max_update(p_instance, p_pad);
+
+ ratio = ratio_calculate(p_instance, p_pad);
+ if (ratio == 0)
+ {
+ return 0;
+ }
+ uint16_t val =
+ (uint16_t)(((uint32_t)(m_nrf_csense.raw_analog_values[p_pad->analog_input_number] -
+ p_instance->min_max[p_pad->pad_index].min_value) *
+ NRF_CSENSE_MAX_VALUE) / ratio);
+ m_values_buffer[p_pad->pad_index+1] = val;
+
+ if (val > max_value)
+ {
+ max_value = val;
+ touched_mask = (1UL << (p_pad->pad_index));
+ }
+ else if (val == max_value)
+ {
+ max_value = val;
+ touched_mask |= (1UL << (p_pad->pad_index));
+ }
+ }
+
+ return touched_mask;
+}
+
+
+/**
+ * @brief Function for finding touched pad.
+ *
+ * If there is more than one pad connected to an analog channel this functions which one was actually touched. This is done by
+ * comparing values of neighboring pads.
+ *
+ * @param [in] instance Pointer to csense instance.
+ * @param [in] touched_mask Mask of touched pads.
+ *
+ * @return Touched pad.
+ */
+static uint16_t find_touched_pad(nrf_csense_instance_t const * p_instance,
+ uint32_t touched_mask)
+{
+ uint8_t i;
+ uint8_t biggest_deviation = 0;
+ uint8_t temp_biggest = 0;
+ uint16_t pad = UINT16_MAX;
+ static uint16_t previous_pad = 0;
+
+ for (i = 0; i < (p_instance->number_of_pads); i++)
+ {
+ if ((1UL << i) & touched_mask)
+ {
+ temp_biggest = m_values_buffer[i];
+ temp_biggest += m_values_buffer[i + 2];
+
+ if ((i != 0) && (i != ((p_instance->number_of_pads-1))))
+ {
+ temp_biggest /= 2;
+ }
+
+ if ((temp_biggest > NRF_CSENSE_PAD_DEVIATION) &&
+ (temp_biggest > biggest_deviation))
+ {
+ biggest_deviation = temp_biggest;
+ pad = i;
+ }
+ }
+ }
+
+ if (pad == UINT16_MAX)
+ {
+ pad = previous_pad;
+ }
+ else
+ {
+ previous_pad = pad;
+ }
+
+ return pad;
+}
+
+
+/**
+ * @brief Function for finding touched step.
+ *
+ * @param [in] instance Pointer to csense instance.
+ *
+ * @return Detected touched step.
+ */
+static uint16_t find_touched_step(nrf_csense_instance_t * p_instance)
+{
+ uint32_t touched_mask = 0;
+ uint16_t pad = 0;
+ uint16_t step;
+
+ touched_mask = find_touched_mask(p_instance);
+
+ if (touched_mask == 0)
+ {
+ return UINT16_MAX;
+ }
+
+ if ((touched_mask & (-(int32_t)touched_mask)) == touched_mask) // Check if there is only one pad with greatest value.
+ {
+ pad = 31 - __CLZ(touched_mask);
+ }
+ else
+ {
+ pad = find_touched_pad(p_instance, touched_mask);
+ }
+
+ step = calculate_step(p_instance, pad);
+ return step;
+}
+
+
+/**
+ * @brief Event handler for csense.
+ *
+ * param [in] p_event_struct Pointer to event structure.
+ */
+static void csense_event_handler(nrf_drv_csense_evt_t * p_event_struct)
+{
+ nrf_csense_evt_t event;
+ static uint16_t prev_analog_values[MAX_ANALOG_INPUTS];
+ bool touched = false;
+ nrf_csense_instance_t * instance;
+ uint8_t i;
+
+ if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_event_struct->analog_channel))) == 0)
+ {
+ return;
+ }
+
+ m_nrf_csense.raw_analog_values[p_event_struct->analog_channel] = p_event_struct->read_value;
+
+ if (nrf_drv_csense_is_busy())
+ {
+ return;
+ }
+
+ for (instance = mp_nrf_csense_instance_head; instance != NULL;
+ instance = instance->p_next_instance) // run through all instances
+ {
+ if (instance->is_active)
+ {
+ event.p_instance = instance;
+ nrf_csense_pad_t * p_pad = instance->p_nrf_csense_pad;
+
+ for (i = 0; i < MAX_ANALOG_INPUTS; i++)
+ {
+ if ((m_nrf_csense.raw_analog_values[i] <
+ (prev_analog_values[i] - NRF_CSENSE_PAD_HYSTERESIS)) ||
+ (m_nrf_csense.raw_analog_values[i] >
+ (prev_analog_values[i] + NRF_CSENSE_PAD_HYSTERESIS)))
+ {
+ touched = true;
+ break;
+ }
+ }
+
+ if (touched)
+ {
+ touched = false;
+
+ for (p_pad = instance->p_nrf_csense_pad; p_pad != NULL;
+ p_pad = p_pad->p_next_pad)
+ {
+ if (m_nrf_csense.raw_analog_values[p_pad->analog_input_number] >
+ p_pad->threshold)
+ {
+ touched = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ // Specify the event
+ if ((instance->is_touched) && touched)
+ {
+ // dragged
+ if (instance->number_of_pads > 1)
+ {
+ event.params.slider.step = find_touched_step(instance);
+ event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_DRAGGED;
+
+ m_nrf_csense.event_handler(&event);
+ }
+ }
+ else if ((!(instance->is_touched)) && touched)
+ {
+ // pressed
+ if (instance->number_of_pads > 1)
+ {
+ event.params.slider.step = find_touched_step(instance);
+ event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_PRESSED;
+ }
+ else
+ {
+ event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_PRESSED;
+ }
+ instance->is_touched = true;
+
+ m_nrf_csense.event_handler(&event);
+ }
+ else if ((instance->is_touched) && (!touched))
+ {
+ // released
+ if (instance->number_of_pads > 1)
+ {
+ event.params.slider.step = find_touched_step(instance);
+ event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_RELEASED;
+ }
+ else
+ {
+ event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_RELEASED;
+ }
+ instance->is_touched = false;
+
+ m_nrf_csense.event_handler(&event);
+ }
+ else
+ {
+ // nothing changed
+ }
+ }
+
+ touched = false;
+ }
+
+ memset(m_values_buffer, 0, sizeof(m_values_buffer));
+ memcpy(prev_analog_values, m_nrf_csense.raw_analog_values,
+ sizeof(m_nrf_csense.raw_analog_values));
+}
+
+
+ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler,
+ uint32_t ticks)
+{
+ ASSERT(event_handler != NULL);
+ ASSERT(m_nrf_csense.state == NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+
+ static const nrf_drv_csense_config_t m_csense_config =
+ {
+ .output_pin = NRF_CSENSE_OUTPUT_PIN
+ };
+
+ m_nrf_csense.event_handler = event_handler;
+ m_nrf_csense.ticks = ticks;
+ mp_nrf_csense_instance_head = NULL;
+
+ err_code = app_timer_create(&nrf_csense_timer, APP_TIMER_MODE_REPEATED, csense_timer_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = nrf_drv_csense_init(&m_csense_config, csense_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ m_nrf_csense.state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_uninit(void)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+ nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head;
+
+ err_code = nrf_drv_csense_uninit();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (m_nrf_csense.enabled_analog_channels_mask != 0)
+ {
+ err_code = app_timer_stop(nrf_csense_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ while ((*pp_instance) != NULL)
+ {
+ nrf_csense_instance_t ** pp_instance_next = (&(*pp_instance)->p_next_instance);
+ (*pp_instance) = NULL;
+ pp_instance = pp_instance_next;
+ }
+
+ memset((void *)&m_nrf_csense, 0, sizeof(nrf_csense_t));
+
+ m_nrf_csense.state = NRFX_DRV_STATE_UNINITIALIZED;
+
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_instance->p_next_instance == NULL);
+ ASSERT(p_instance != NULL);
+
+ ret_code_t err_code;
+
+ nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head;
+
+ while ((*pp_instance) != NULL)
+ {
+ ASSERT((*pp_instance) != p_instance);
+ pp_instance = &((*pp_instance)->p_next_instance);
+ }
+
+ *pp_instance = p_instance;
+
+ err_code = nrf_csense_enable(p_instance);
+ return err_code;
+}
+
+ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_instance != NULL);
+
+ ret_code_t err_code;
+ nrf_csense_pad_t const * p_pad;
+ uint8_t analog_channels_mask = 0;
+
+ if (m_nrf_csense.enabled_analog_channels_mask == 0)
+ {
+ err_code = app_timer_start(nrf_csense_timer, m_nrf_csense.ticks, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ p_instance->is_active = true;
+
+ for (p_pad = p_instance->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad)
+ {
+ p_instance->min_max[p_pad->pad_index].min_value = UINT16_MAX;
+
+ // If channel was already enabled skip it.
+ if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_pad->analog_input_number))) == 0)
+ {
+ analog_channels_mask |= (1UL << (p_pad->analog_input_number));
+ m_nrf_csense.enabled_analog_channels_mask |= (1UL << (p_pad->analog_input_number));
+ }
+ }
+
+ m_nrf_csense.state = NRFX_DRV_STATE_POWERED_ON;
+ nrf_drv_csense_channels_enable(analog_channels_mask);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance)
+{
+ ASSERT(m_nrf_csense.state == NRFX_DRV_STATE_POWERED_ON);
+
+ ret_code_t err_code;
+ nrf_csense_instance_t * p_instance_temp = mp_nrf_csense_instance_head;
+ nrf_csense_pad_t const * p_pad;
+ uint8_t channels_mask = 0;
+ uint8_t instance_channels_mask = 0;
+
+ for (p_instance_temp = mp_nrf_csense_instance_head; p_instance_temp != NULL;
+ p_instance_temp = p_instance_temp->p_next_instance)
+ {
+ for (p_pad = p_instance_temp->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad)
+ {
+ if (p_instance_temp == p_instance)
+ {
+ instance_channels_mask |= (1UL << (p_pad->analog_input_number));
+ p_instance->is_active = false;
+ }
+ else
+ {
+ channels_mask |= (1UL << (p_pad->analog_input_number));
+ }
+ }
+ }
+
+ nrf_drv_csense_channels_disable((~channels_mask) & instance_channels_mask);
+
+ m_nrf_csense.enabled_analog_channels_mask = channels_mask;
+
+ if (m_nrf_csense.enabled_analog_channels_mask == 0)
+ {
+ err_code = app_timer_stop(nrf_csense_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ m_nrf_csense.state = NRFX_DRV_STATE_INITIALIZED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_ticks_set(uint32_t ticks)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+
+ if (nrf_drv_csense_is_busy())
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ m_nrf_csense.ticks = ticks;
+
+ if (m_nrf_csense.state == NRFX_DRV_STATE_POWERED_ON)
+ {
+ err_code = app_timer_stop(nrf_csense_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = app_timer_start(nrf_csense_timer, ticks, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps)
+{
+ if (p_instance->is_active)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_instance->steps = steps;
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(NRF_CSENSE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h
new file mode 100644
index 0000000..707d3ae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h
@@ -0,0 +1,344 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CSENSE_H__
+#define NRF_CSENSE_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "app_timer.h"
+#include "nrf_drv_csense.h"
+#include "nrf_csense_macros.h"
+#include "app_util.h"
+
+/** @file
+ *
+ * @defgroup nrf_csense Capacitive sensor library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for using the capacitive sensor library with support for many instances of sliders, wheels, and buttons.
+ */
+
+/**
+ * @brief Macro for returning the address of a variable.
+ */
+#define NRF_CSENSE_GET_INSTANCE_ID(instance) (&instance)
+
+/**
+ * @brief Statically allocate memory for the instance of a capacitive sensor.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_BUTTON_DEF(name, p1) NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1)
+
+/**
+ * @brief Macro for creating a 2-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_2_DEF(name, steps_no, p1, p2) NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2)
+
+/**
+ * @brief Macro for creating a 3-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3)
+
+/**
+ * @brief Macro for creating a 4-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4)
+
+/**
+ * @brief Macro for creating a 5-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5)
+
+/**
+ * @brief Macro for creating a 3-pad wheel instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_WHEEL_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3)
+
+/**
+ * @brief Macro for creating a 4-pad wheel instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4)
+
+/**
+ * @brief Macro for creating a 5-pad wheel instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5)
+
+/**
+ * @cond (NODOX)
+ * @defgroup nrf_csense_internal Auxiliary internal types declarations
+ * @brief Module for internal usage inside the library only.
+ * @details These definitions are available to the user, but they should not
+ * be accessed directly. Use the API to access them.
+ * @{
+ *
+ */
+
+ /*
+ * @brief Forward declaration of capacitive sensor instance.
+ */
+ typedef struct nrf_csense_instance_s nrf_csense_instance_t;
+
+ /*
+ * @brief Forward declaration of a capacitive sensor pad.
+ */
+ typedef struct nrf_csense_pad_s nrf_csense_pad_t;
+
+ /**
+ * @brief Structure with pointer to min and max values measured on pads.
+ */
+ typedef struct
+ {
+ uint16_t max_value; //!< Max value measured on pads.
+ uint16_t min_value; //!< Min value measured on pads.
+ }nrf_csense_min_max_t;
+
+ /**
+ * @brief Structure with single instance parameters. This can be either a slider or a button.
+ */
+ struct nrf_csense_instance_s
+ {
+ nrf_csense_instance_t * p_next_instance; //!< Pointer to the next instance.
+ nrf_csense_pad_t * p_nrf_csense_pad; //!< Pointer to the first pad of the module.
+ nrf_csense_min_max_t * min_max; //!< Structure with pointers to min and max values measured on pads.
+ uint16_t steps; //!< Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ uint8_t number_of_pads; //!< Number of pads that the instance is using.
+ bool is_active; //!< Flag to indicate if the instance is active.
+ bool is_touched; //!< Flag to indicate if the instance is touched.
+ void * p_context; //!< General purpose pointer.
+ };
+
+ /* Structure with single pad parameters used for initialization. */
+ struct nrf_csense_pad_s
+ {
+ nrf_csense_pad_t * p_next_pad; //!< Pointer to the next pad.
+ uint16_t threshold; //!< Threshold voltage on pad/time of charging to decide if the pad was touched.
+ uint8_t pad_index; //!< Index of the pad.
+ uint8_t analog_input_number; //!< Analog input connected to the pad.
+ };
+
+/** @}
+ * @endcond
+ */
+
+/**
+ * @brief Enum for nrf_csense events.
+ */
+typedef enum
+{
+ NRF_CSENSE_BTN_EVT_PRESSED, //!< Event for pad pressed.
+ NRF_CSENSE_BTN_EVT_RELEASED, //!< Event for pad released.
+ NRF_CSENSE_SLIDER_EVT_PRESSED, //!< Event for pad pressed.
+ NRF_CSENSE_SLIDER_EVT_RELEASED, //!< Event for pad released.
+ NRF_CSENSE_SLIDER_EVT_DRAGGED, //!< Event for pad dragged.
+}nrf_csense_evt_type_t;
+
+/**
+ * @brief Structure with slider event data including the measured step.
+ */
+typedef struct
+{
+ uint16_t step; //!< Measured step.
+} nrf_csense_slider_evt_t;
+
+/**
+ * @brief Event data union for nrf_csense events.
+ */
+typedef union
+{
+ nrf_csense_slider_evt_t slider; //!< Structure with slider event data including the measured step.
+} nrf_csense_evt_param_t;
+
+/**
+ * @brief Structure with event parameters.
+ */
+typedef struct
+{
+ nrf_csense_evt_type_t nrf_csense_evt_type; //!< Type of event.
+ nrf_csense_instance_t * p_instance; //!< Pointer to instance.
+ nrf_csense_evt_param_t params; //!< Event data union for nrf_csense events.
+}nrf_csense_evt_t;
+
+/**
+ * @brief Capacitive sensor handler type.
+ */
+typedef void (* nrf_csense_event_handler_t)(nrf_csense_evt_t * p_evt);
+
+/**
+ * @brief Function for setting a handler of the instance.
+ *
+ * @param [in] p_instance Pointer to the instance whose steps are going to be changed.
+ * @param [in] p_context General purpose pointer. Will be passed to the callback function.
+ */
+__STATIC_INLINE void nrf_csense_instance_context_set(nrf_csense_instance_t * const p_instance, void * p_context)
+{
+ p_instance->p_context = p_context;
+}
+
+/**
+ * @brief Function for initializing the module. After initialization, no instances are enabled.
+ *
+ * @param [in] event_handler Event handler for the Capacitive Sensor module.
+ * @param [in] ticks Time in app_timer ticks between next conversions.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameter was provided.
+ * @retval NRF_ERROR_INVALID_STATE If one of the used modules is in invalid state.
+ * @retval NRF_ERROR_INTERNAL If an error occured while initializing one of the modules used by the capacitive sensor library.
+ * @retval NRF_SUCCESS If the module was initialized successfully.
+ */
+ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler, uint32_t ticks);
+
+/**
+ * @brief Function for uninitializing the module.
+ *
+ * @return Values returned by @ref nrf_drv_csense_uninit and @ref app_timer_stop.
+ */
+ret_code_t nrf_csense_uninit(void);
+
+/**
+ * @brief Function for adding an instance of capacitive sensor to a linked list.
+ *
+ * The function calls @ref nrf_csense_enable to enable the instance that was added to the linked list.
+ *
+ * @param [in] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred.
+ *
+ * @return Values returned by @ref nrf_csense_enable.
+ */
+ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance);
+
+/**
+ * @brief Function for enabling a single instance.
+ *
+ * @param [in,out] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred.
+ *
+ * @return Values returned by @ref app_timer_start.
+ */
+ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance);
+
+/**
+ * @brief Function for disabling an instance.
+ *
+ * @param [in] p_instance Pointer to the instance to be disabled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If the instance was already disabled.
+ * @retval NRF_SUCCESS If the instance was disabled successfully.
+ */
+ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance);
+
+/**
+ * @brief Function for setting ticks between next measurements.
+ *
+ * @param [in] ticks New time between conversions in app_timer ticks.
+ *
+ * @retval NRF_ERROR_BUSY If the capacitive sensor was busy.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter was provided.
+ * @retval NRF_ERROR_INVALID_STATE If app_timer was in invalid state.
+ * @retval NRF_SUCCESS If ticks were set successfully.
+ */
+ret_code_t nrf_csense_ticks_set(uint32_t ticks);
+
+/**
+ * @brief Function for setting steps of an instance.
+ *
+ * Note that you have do disable the instance before you can change its number of steps.
+ *
+ * @param [in] p_instance Pointer to the instance whose steps are going to be changed.
+ * @param [in] steps New steps value.
+ *
+ * @retval NRF_ERROR_BUSY If the capacitive sensor was busy.
+ * @retval NRF_SUCCESS If steps were set successfully.
+ */
+ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps);
+
+
+/** @} */
+
+#endif //NRF_CSENSE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h
new file mode 100644
index 0000000..0e8a297
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h
@@ -0,0 +1,359 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_CSENSE_MACROS_H__
+#define NRF_CSENSE_MACROS_H__
+
+/** @file
+ *
+ * @defgroup nrf_csense_macros Capacitive sensor macros
+ * @{
+ * @ingroup nrf_csense
+ *
+ * @brief A set of macros to facilitate creation of a new capacitive sensor instance.
+ */
+
+#define NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad) = \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }; \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax); \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = &CONCAT_2(name, _pad), \
+ .min_max = &CONCAT_2(name, _minmax), \
+ .steps = 1, \
+ .number_of_pads = 1, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[2] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[2]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 2, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[3] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[3]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 3, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ } \
+ }; \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 4, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[4], \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p5, \
+ .pad_index = 4, \
+ .analog_input_number = GET_ARG_1 p5 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 5, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p1 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 4, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+
+#define NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[4], \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 4, \
+ .analog_input_number = GET_ARG_1 p1 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 5, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5)\
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[6] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[4], \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[5], \
+ .threshold = GET_ARG_2 p5, \
+ .pad_index = 4, \
+ .analog_input_number = GET_ARG_1 p5 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 5, \
+ .analog_input_number = GET_ARG_1 p1 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[6]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 6, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+/** @} */
+
+#endif // NRF_CSENSE_MACROS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c
new file mode 100644
index 0000000..8adf52a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c
@@ -0,0 +1,633 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_DRV_CSENSE)
+#include "nrf_drv_csense.h"
+#include "nrf_peripherals.h"
+#include "nrf_gpio.h"
+#include "app_error.h"
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+#include "string.h"
+#include <stdio.h>
+
+#if defined(__CORTEX_M) && (__CORTEX_M < 4)
+#ifndef ARM_MATH_CM0PLUS
+#define ARM_MATH_CM0PLUS
+#endif
+/*lint -save -e689 */
+#include "arm_math.h"
+/*lint -restore */
+#endif
+
+#if USE_COMP
+#include "nrf_drv_comp.h"
+#include "nrf_drv_ppi.h"
+#include "nrf_drv_timer.h"
+#endif //USE_COMP
+
+#if USE_COMP == 0
+#ifdef ADC_PRESENT
+#include "nrfx_adc.h"
+
+/**
+ * @defgroup adc_defines ADC defines to count input voltage.
+ * @{
+ */
+#define ADC_RES_10BIT 1024
+#define ADC_INPUT_PRESCALER 3
+#define ADC_REF_VBG_VOLTAGE 1.2
+/* @} */
+
+/* ADC channel used to call conversion. */
+static nrfx_adc_channel_t adc_channel = NRFX_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_0);
+#elif defined(SAADC_PRESENT)
+#include "nrf_drv_saadc.h"
+
+/**
+ * @defgroup saadc_defines SAADC defines to count input voltage.
+ * @{
+ */
+#define SAADC_RES_10BIT 1024
+#define SAADC_INPUT_PRESCALER 3
+#define SAADC_REF_VBG_VOLTAGE 0.6
+/* @} */
+
+/* SAADC channel used to call conversion. */
+static nrf_saadc_channel_config_t saadc_channel = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+#if USE_COMP
+/* Number of channels required by PPI. */
+#define PPI_REQUIRED_CHANNELS 3
+
+/* Array of PPI channels. */
+static nrf_ppi_channel_t m_ppi_channels[PPI_REQUIRED_CHANNELS];
+
+
+/**
+ * @defgroup timer_instances Timer instances.
+ * @{
+ */
+static const nrf_drv_timer_t m_timer0 = NRF_DRV_TIMER_INSTANCE(TIMER0_FOR_CSENSE);
+static const nrf_drv_timer_t m_timer1 = NRF_DRV_TIMER_INSTANCE(TIMER1_FOR_CSENSE);
+/* @} */
+#endif //USE_COMP
+
+/* Configuration of the capacitive sensor module. */
+typedef struct
+{
+ volatile nrfx_drv_state_t module_state; /**< State of the module. */
+ nrf_drv_csense_event_handler_t event_handler; /**< Event handler for capacitor sensor events. */
+ uint16_t analog_values[MAX_ANALOG_INPUTS]; /**< Array containing analog values measured on the corresponding COMP/ADC channel. */
+ volatile bool busy; /**< Indicates state of module - busy if there are ongoing conversions. */
+ volatile uint8_t cur_chann_idx; /**< Current channel to be read if enabled. */
+ volatile uint8_t adc_channels_input_mask; /**< Enabled channels. */
+ uint8_t output_pin; /**< Pin to generate signal charging capacitors. */
+ uint8_t channels_to_read; /**< Mask of channels remaining to be read in the current measurement. */
+ volatile bool timers_powered_on; /**< Flag to indicate if timers were already started. */
+}csense_t;
+
+static csense_t m_csense;
+
+/**
+ * @brief Function for determining the next analog channel to be read.
+ */
+__STATIC_INLINE void calculate_next_channel(void)
+{
+ m_csense.cur_chann_idx = 31 - __CLZ(m_csense.channels_to_read);
+}
+
+/**
+ * @brief Function for handling conversion values.
+ *
+ * @param[in] val Value received from ADC or COMP.
+ */
+static void conversion_handler(uint16_t val)
+{
+ nrf_drv_csense_evt_t event_struct;
+
+#if USE_COMP == 0
+ nrf_gpio_pin_set(m_csense.output_pin);
+#endif //USE_COMP
+
+ m_csense.analog_values[m_csense.cur_chann_idx] = val;
+
+ event_struct.read_value = val;
+ event_struct.analog_channel = m_csense.cur_chann_idx;
+
+ m_csense.channels_to_read &= ~(1UL<<m_csense.cur_chann_idx);
+
+ // decide if there will be more conversions
+ if (m_csense.channels_to_read == 0)
+ {
+ m_csense.busy = false;
+#if USE_COMP == 0 && defined(SAADC_PRESENT)
+ nrf_saadc_disable();
+#endif
+ }
+
+ m_csense.event_handler(&event_struct);
+
+ if (m_csense.channels_to_read > 0) // Start new conversion.
+ {
+ ret_code_t err_code;
+ calculate_next_channel();
+ err_code = nrf_drv_csense_sample();
+ if (err_code != NRF_SUCCESS)
+ {
+ return;
+ }
+ }
+}
+
+#if USE_COMP
+/**
+ * @brief Timer0 interrupt handler.
+ *
+ * @param[in] event_type Timer event.
+ * @param[in] p_context General purpose parameter set during initialization of
+ * the timer. This parameter can be used to pass
+ * additional information to the handler function, for
+ * example, the timer ID.
+ */
+static void counter_compare_handler(nrf_timer_event_t event_type, void* p_context)
+{
+ if (event_type == NRF_TIMER_EVENT_COMPARE0)
+ {
+ uint16_t val = nrf_drv_timer_capture_get(&m_timer1, NRF_TIMER_CC_CHANNEL1);
+ nrf_drv_timer_pause(&m_timer1);
+ nrf_drv_timer_clear(&m_timer1);
+
+ /* Handle finished measurement. */
+ conversion_handler(val);
+ }
+}
+
+/**
+ * @brief Dummy handler.
+ *
+ * @param[in] event_type Timer event.
+ * @param[in] p_context General purpose parameter set during initialization of
+ * the timer. This parameter can be used to pass
+ * additional information to the handler function, for
+ * example, the timer ID.
+ */
+static void dummy_handler(nrf_timer_event_t event_type, void* p_context){}
+
+/**
+ * @brief Function for initializing timers.
+ *
+ * @retval NRF_ERROR_INTERNAL If there were error initializing timers.
+ * @retval NRF_SUCCESS If timers were initialized successfully.
+ */
+static ret_code_t timer_init(void)
+{
+ ret_code_t err_code;
+
+ //set first timer in timer mode to get period of relaxation oscillator
+ nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG;
+ timer_config.mode = NRF_TIMER_MODE_TIMER;
+ err_code = nrf_drv_timer_init(&m_timer1, &timer_config, dummy_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //set second timer in counter mode and generate event on tenth period
+ timer_config.mode = NRF_TIMER_MODE_COUNTER;
+ err_code = nrf_drv_timer_init(&m_timer0, &timer_config, counter_compare_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ nrf_drv_timer_extended_compare(&m_timer0, NRF_TIMER_CC_CHANNEL0, MEASUREMENT_PERIOD, (nrf_timer_short_mask_t)(NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE0_STOP_MASK), true);
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Function for initializing and enabling PPI channels.
+ *
+ * @retval NRF_ERROR_INTERNAL If there were error initializing or enabling PPI channels.
+ * @retval NRF_SUCCESS If PPI channels were initialized and enabled successfully.
+ */
+static ret_code_t ppi_init(void)
+{
+ ret_code_t err_code;
+ uint8_t i;
+
+ err_code = nrf_drv_ppi_init();
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ for (i = 0; i < PPI_REQUIRED_CHANNELS ; i++)
+ {
+ err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channels[i]);
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[0], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_CROSS), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_COUNT));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[1], nrf_drv_timer_event_address_get(&m_timer0, NRF_TIMER_EVENT_COMPARE0), nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CAPTURE1));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[1], nrf_drv_comp_task_address_get(NRF_COMP_TASK_STOP));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[2], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_READY), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_CLEAR));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[2], nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CLEAR));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ for (i = 0; i < PPI_REQUIRED_CHANNELS ; i++)
+ {
+ err_code = nrf_drv_ppi_channel_enable(m_ppi_channels[i]);
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Dummy handler for COMP events.
+ *
+ * @param[in] event COMP event.
+ */
+static void comp_event_handler(nrf_comp_event_t event){}
+
+/**
+ * @brief Function for initializing COMP module in relaxation oscillator mode.
+ *
+ * @note The frequency of the oscillator depends on threshold voltages, current source and capacitance of pad and can be calculated as f_OSC = I_SOURCE / (2C·(VUP-VDOWN) ).
+ *
+ * @retval NRF_ERROR_INTERNAL If there were error while initializing COMP driver.
+ * @retval NRF_SUCCESS If the COMP driver initialization was successful.
+ */
+static ret_code_t comp_init(void)
+{
+ ret_code_t err_code;
+ nrf_drv_comp_config_t m_comp_config = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0);
+
+ /* Workaround for Errata 12 "COMP: Reference ladder is not correctly calibrated" found at the Errata document
+ for your device located at https://infocenter.nordicsemi.com/ */
+ *(volatile uint32_t *)0x40013540 = (*(volatile uint32_t *)0x10000324 & 0x00001F00) >> 8;
+
+ m_comp_config.isource = NRF_COMP_ISOURCE_Ien10uA;
+
+ err_code = nrf_drv_comp_init(&m_comp_config, comp_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+#endif //USE_COMP
+
+#if USE_COMP == 0
+#ifdef ADC_PRESENT
+/**
+ * @brief ADC handler.
+ *
+ * @param[in] p_event Pointer to analog-to-digital converter driver event.
+ */
+void adc_handler(nrfx_adc_evt_t const * p_event)
+{
+ nrf_gpio_pin_set(m_csense.output_pin);
+ uint16_t val;
+ val = (uint16_t)(p_event->data.sample.sample *
+ ADC_REF_VBG_VOLTAGE * 1000 *
+ ADC_INPUT_PRESCALER / ADC_RES_10BIT);
+ conversion_handler(val);
+}
+
+/**
+ * @brief Function for initializing ADC.
+ */
+static ret_code_t adc_init(void)
+{
+ ret_code_t err_code;
+
+ adc_channel.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
+
+ nrfx_adc_config_t const adc_config = NRFX_ADC_DEFAULT_CONFIG;
+ err_code = nrfx_adc_init(&adc_config, adc_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_gpio_pin_set(m_csense.output_pin);
+
+ return NRF_SUCCESS;
+}
+#elif defined(SAADC_PRESENT)
+/**
+ * @brief SAADC handler.
+ *
+ * @param[in] p_event Pointer to analog-to-digital converter driver event.
+ */
+void saadc_handler(nrf_drv_saadc_evt_t const * p_event)
+{
+ nrf_gpio_pin_set(m_csense.output_pin);
+ uint16_t val;
+ (void)nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
+ val = (uint16_t)(*p_event->data.done.p_buffer *
+ SAADC_REF_VBG_VOLTAGE * 1000 *
+ SAADC_INPUT_PRESCALER / SAADC_RES_10BIT);
+ conversion_handler(val);
+}
+
+/**
+ * @brief Function for initializing SAADC.
+ */
+static ret_code_t saadc_init(void)
+{
+ ret_code_t err_code;
+ static nrf_saadc_value_t saadc_value;
+
+ saadc_channel.gain = NRF_SAADC_GAIN1_3;
+
+ err_code = nrf_drv_saadc_init(NULL, saadc_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_gpio_pin_set(m_csense.output_pin);
+
+ err_code = nrf_drv_saadc_channel_init(0, &saadc_channel);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = nrf_drv_saadc_buffer_convert(&saadc_value, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_saadc_disable();
+
+ return NRF_SUCCESS;
+}
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler)
+{
+ ASSERT(m_csense.module_state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_config->output_pin <= NUMBER_OF_PINS);
+
+ ret_code_t err_code;
+
+ if (p_config == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (event_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_csense.busy = false;
+
+#if USE_COMP == 0
+ m_csense.output_pin = p_config->output_pin;
+ nrf_gpio_cfg_output(m_csense.output_pin);
+ nrf_gpio_pin_set(m_csense.output_pin);
+#endif //COMP_PRESENT
+
+ m_csense.event_handler = event_handler;
+
+#if USE_COMP
+ err_code = comp_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = timer_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = ppi_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#else
+#ifdef ADC_PRESENT
+ err_code = adc_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#elif defined(SAADC_PRESENT)
+ err_code = saadc_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+ m_csense.module_state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_drv_csense_uninit(void)
+{
+ ASSERT(m_csense.module_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ nrf_drv_csense_channels_disable(0xFF);
+
+#if USE_COMP
+ ret_code_t err_code;
+ uint8_t i;
+
+ nrf_drv_timer_uninit(&m_timer0);
+ nrf_drv_timer_uninit(&m_timer1);
+ nrf_drv_comp_uninit();
+ for (i =0; i < 3; i++)
+ {
+ err_code = nrf_drv_ppi_channel_free(m_ppi_channels[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ err_code = nrf_drv_ppi_uninit();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#else
+#ifdef ADC_PRESENT
+ nrfx_adc_uninit();
+#elif defined(SAADC_PRESENT)
+ nrf_drv_saadc_uninit();
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+ m_csense.module_state = NRFX_DRV_STATE_UNINITIALIZED;
+
+ memset((void*)&m_csense, 0, sizeof(m_csense));
+
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_csense_channels_enable(uint8_t channels_mask)
+{
+ ASSERT(m_csense.module_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ m_csense.busy = true;
+
+ m_csense.module_state = NRFX_DRV_STATE_POWERED_ON;
+
+ m_csense.adc_channels_input_mask |= channels_mask;
+
+ m_csense.busy = false;
+}
+
+void nrf_drv_csense_channels_disable(uint8_t channels_mask)
+{
+ ASSERT(m_csense.module_state == NRFX_DRV_STATE_POWERED_ON);
+
+ m_csense.adc_channels_input_mask &= ~channels_mask;
+
+ if (m_csense.adc_channels_input_mask == 0)
+ {
+ m_csense.module_state = NRFX_DRV_STATE_INITIALIZED;
+ }
+}
+
+uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel)
+{
+ return m_csense.analog_values[csense_channel];
+}
+
+ret_code_t nrf_drv_csense_sample(void)
+{
+ ASSERT(m_csense.module_state == NRFX_DRV_STATE_POWERED_ON);
+
+ if (m_csense.adc_channels_input_mask != 0)
+ {
+ if (m_csense.channels_to_read == 0)
+ {
+#if USE_COMP == 0 && defined(SAADC_PRESENT)
+ nrf_saadc_enable();
+#endif
+ if (nrf_drv_csense_is_busy() == true)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ m_csense.busy = true;
+ m_csense.channels_to_read = m_csense.adc_channels_input_mask;
+ calculate_next_channel();
+ }
+
+#if USE_COMP
+ if (!m_csense.timers_powered_on)
+ {
+ nrf_drv_timer_enable(&m_timer0);
+ nrf_drv_timer_enable(&m_timer1);
+ m_csense.timers_powered_on = true;
+ }
+ else
+ {
+ nrf_drv_timer_resume(&m_timer0);
+ nrf_drv_timer_resume(&m_timer1);
+ }
+ nrf_drv_comp_pin_select((nrf_comp_input_t)m_csense.cur_chann_idx);
+ nrf_drv_comp_start(0, 0);
+#else
+ ret_code_t err_code;
+#ifdef ADC_PRESENT
+ adc_channel.config.config.ain = (nrf_adc_config_input_t)(1<<m_csense.cur_chann_idx);
+ nrf_gpio_pin_clear(m_csense.output_pin);
+ err_code = nrfx_adc_sample_convert(&adc_channel, NULL);
+#elif defined(SAADC_PRESENT)
+ saadc_channel.pin_p = (nrf_saadc_input_t)(m_csense.cur_chann_idx + 1);
+ nrf_saadc_channel_input_set(0, saadc_channel.pin_p, NRF_SAADC_INPUT_DISABLED);
+ nrf_gpio_pin_clear(m_csense.output_pin);
+ err_code = nrf_drv_saadc_sample();
+#endif //ADC_PRESENT
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#endif //USE_COMP
+ }
+
+ return NRF_SUCCESS;
+}
+
+bool nrf_drv_csense_is_busy(void)
+{
+ return m_csense.busy;
+}
+#endif //NRF_MODULE_ENABLED(NRF_DRV_CSENSE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h
new file mode 100644
index 0000000..e60bd9d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_DRV_CSENSE_H__
+#define NRF_DRV_CSENSE_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "app_timer.h"
+
+/** @file
+ *
+ * @defgroup nrf_drv_csense Capacitive sensor low-level library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for using the capacitive sensor on low-energy level.
+ */
+
+/** @brief Maximum number of analog inputs. */
+#define MAX_ANALOG_INPUTS 8
+
+/**
+ * @brief Module initializing structure.
+ */
+typedef struct
+{
+ uint8_t output_pin; /**< Pin on which to generate voltage for charging the capacitors. */
+}nrf_drv_csense_config_t;
+
+/**
+ * @brief Structure holding event parameters.
+ */
+typedef struct
+{
+ uint16_t read_value; /**< Value which was read on the analog channel. For nRF51, this value is voltage in millivolts. For nRF52, it is time in ticks of 10 periods of the relaxation oscillator. Voltage corresponds to capacitance of the pad attached to analog channel and gets higher once it
+ is touched. Period of relaxation also corresponds to the pad capacitance and increases its value when capacitance gets
+ higher. */
+ uint8_t analog_channel; /**< Index of the analog channel from which the value was read. */
+}nrf_drv_csense_evt_t;
+
+/**
+ * @brief Capacitive sensor event handler. Called from conversion handler.
+ *
+ * @param[in] event_struct Structure holding event parameters.
+ */
+typedef void (* nrf_drv_csense_event_handler_t) (nrf_drv_csense_evt_t * p_event_struct);
+
+/**
+ * @brief Function for initializing the module.
+ *
+ * @details After calling this function, the module is in initialized state and all channels are disabled. The @ref nrf_drv_csense_channels_enable
+ * function must be called. This function initializes all modules required by the capacitive sensor library: ADC for (nRF51) or TIMERs, PPIs, and COMP (for nRF52).
+ *
+ * @param[in] p_config Structure for initializing the module.
+ * @param[in] event_handler Event handler for capacitive sensor events.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Invalid parameter.
+ * @retval NRF_ERROR_NO_MEM Timer operations queue was full.
+ * @retval NRF_ERROR_INTERNAL Error occurred during timers, PPI's, or COMP initialization.
+ * @retval NRF_SUCCESS Module was initialized successfully.
+ *
+ * @sa nrf_drv_csense_channels_enable
+ */
+ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler);
+
+/**
+ * @brief Function for unintializing the capacitive sensor. Clears the mask of enabled channels.
+ *
+ * @return Values returned by @ref nrf_drv_ppi_channel_free.
+ */
+ret_code_t nrf_drv_csense_uninit(void);
+
+/**
+ * @brief Function for enabling analog channels for the capacitive sensor.
+ *
+ * @param[in] channels_mask Mask of analog channels to be enabled.
+ */
+void nrf_drv_csense_channels_enable(uint8_t channels_mask);
+
+/**
+ * @brief Function for disabling analog channels of the capacitive sensor.
+ *
+ * @param[in] channels_mask Mask of analog channels to be disabled.
+ */
+void nrf_drv_csense_channels_disable(uint8_t channels_mask);
+
+/**
+ * @brief Function for getting the last read value from an analog channel.
+ *
+ * @param[in] csense_channel Number of the channel to get the value from.
+ *
+ * @return Analog value measured on the channel.
+ */
+uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel);
+
+/**
+ * @brief Function for triggering a measurement on all enabled analog channels. The handler will be called on every completed measurement.
+ *
+ * @retval NRF_ERROR_BUSY If the module was busy or SAADC module is in use and was busy.
+ * @retval NRF_SUCCESS If the measurement was triggered successfully.
+ */
+ret_code_t nrf_drv_csense_sample(void);
+
+/**
+ * @brief Function for checking if the module is busy.
+ *
+ * @return True if busy or false if not busy.
+ */
+bool nrf_drv_csense_is_busy(void);
+
+/** @} */
+
+#endif //NRF_DRV_CSENSE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h
new file mode 100644
index 0000000..2a6faf2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _NRF_DELAY_H
+#define _NRF_DELAY_H
+
+#include <nrfx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for delaying execution for a number of microseconds.
+ *
+ * @param us_time Number of microseconds to wait.
+ */
+#define nrf_delay_us(us_time) NRFX_DELAY_US(us_time)
+
+
+/**
+ * @brief Function for delaying execution for a number of milliseconds.
+ *
+ * @param ms_time Number of milliseconds to wait.
+ */
+
+__STATIC_INLINE void nrf_delay_ms(uint32_t ms_time)
+{
+ if (ms_time == 0)
+ {
+ return;
+ }
+
+ do {
+ nrf_delay_us(1000);
+ } while (--ms_time);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c
new file mode 100644
index 0000000..cbc3d9d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * @brief Elliptic Curve Cryptography Interface
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "app_timer.h"
+#include "app_util.h"
+#include "nrf_log.h"
+#include "nrf_drv_rng.h"
+#include "ecc.h"
+
+#include "uECC.h"
+
+
+static int ecc_rng(uint8_t *dest, unsigned size)
+{
+ nrf_drv_rng_block_rand(dest, (uint32_t) size);
+ return 1;
+}
+
+void ecc_init(bool rng)
+{
+ if (rng)
+ {
+ uECC_set_rng(ecc_rng);
+ }
+}
+
+ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t *p_le_pk)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_pk)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ int ret = uECC_make_key((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t *p_le_pk)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_pk)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_compute_public_key");
+ int ret = uECC_compute_public_key((uint8_t *) p_le_sk, (uint8_t *) p_le_pk, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //NRF_LOG_INFO("uECC_compute_public_key complete: %d", ret);
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const *p_le_pk, uint8_t *p_le_ss)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_pk || !p_le_ss)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk) || !is_word_aligned(p_le_ss))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_shared_secret");
+ int ret = uECC_shared_secret((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_le_ss, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //NRF_LOG_INFO("uECC_shared_secret complete: %d", ret);
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_hash || !p_le_sig)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_sign");
+ int ret = uECC_sign((const uint8_t *) p_le_sk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //NRF_LOG_INFO("uECC_sign complete: %d", ret);
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_pk || !p_le_hash || !p_le_sig)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_pk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_verify");
+ int ret = uECC_verify((const uint8_t *) p_le_pk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ //NRF_LOG_INFO("uECC_verify complete: %d", ret);
+ return NRF_SUCCESS;
+
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h
new file mode 100644
index 0000000..95983ec
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * @defgroup ecc Elliptic Curve Cryptography interface
+ * @{
+ * @ingroup app_common
+ * @brief Elliptic Curve Cryptography interface
+ */
+
+#ifndef ECC_H__
+#define ECC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ECC_P256_SK_LEN 32
+#define ECC_P256_PK_LEN 64
+
+/**@brief Initialize the ECC module.
+ *
+ * @param[in] rng Use a random number generator.
+ *
+ * */
+void ecc_init(bool rng);
+
+/**@brief Create a public/private key pair.
+ *
+ * @param[out] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Key pair successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during key generation.
+ */
+ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t* p_le_pk);
+
+/**@brief Create a public key from a provided private key.
+ *
+ * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Public key successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during key generation.
+ */
+ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t* p_le_pk);
+
+/**@brief Create a shared secret from a provided public/private key pair.
+ *
+ * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ * @param[out] p_le_ss Shared secret. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Shared secret successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during key generation.
+ */
+ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const * p_le_pk, uint8_t *p_le_ss);
+
+/**@brief Sign a hash or digest using a private key.
+ *
+ * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] hlen Hash length in bytes.
+ * @param[out] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Signature successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during signature generation.
+ */
+ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig);
+
+/**@brief Verify a signature using a public key.
+ *
+ * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] hlen Hash length in bytes.
+ * @param[in] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Signature verified.
+ * @retval NRF_ERROR_INVALID_DATA Signature failed verification.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during signature verification.
+ */
+ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ECC_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c
new file mode 100644
index 0000000..6f44d0b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c
@@ -0,0 +1,578 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_libuarte.h"
+#include "nrfx_ppi.h"
+#include "nrf_uarte.h"
+#include "nrf_gpio.h"
+#include "nrfx_timer.h"
+
+
+
+#define NRF_LOG_MODULE_NAME libUARTE
+#if NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#else // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define INTERRUPTS_MASK \
+ (NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_RXSTARTED_MASK | NRF_UARTE_INT_ERROR_MASK | \
+ NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_TXSTOPPED_MASK)
+
+#define UART_DRV_UARTE CONCAT_2(NRF_UARTE, NRF_LIBUARTE_CONFIG_UARTE_USED)
+
+#if NRF_LIBUARTE_CONFIG_UARTE_USED == 0
+#define UART_DRV_IRQn UARTE0_UART0_IRQn
+#define UART_DRV_IRQHandler UARTE0_UART0_IRQHandler
+#define MAX_DMA_XFER_LEN (1<<UARTE0_EASYDMA_MAXCNT_SIZE)
+#elif NRF_LIBUARTE_CONFIG_UARTE_USED == 1
+#define UART_DRV_IRQn UARTE1_UART1_IRQn
+#define UART_DRV_IRQHandler UARTE1_IRQHandler
+#define MAX_DMA_XFER_LEN (1<<UARTE1_EASYDMA_MAXCNT_SIZE)
+#endif
+
+typedef enum
+{
+ PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX,
+ PPI_CH_RXSTARTED_EXT_TSK,
+ PPI_CH_EXT_STOP_STOPRX,
+ PPI_CH_EXT_STOP_GROUPS_EN,
+ PPI_CH_RXRDY_TIMER_COUNT,
+
+ PPI_CH_RX_MAX,
+ PPI_CH_ENDRX_STARTRX = PPI_CH_RX_MAX,
+ PPI_CH_ENDRX_EXT_TSK,
+
+ PPI_CH_RX_GROUP_MAX,
+
+ PPI_CH_ENDTX_STARTTX = PPI_CH_RX_GROUP_MAX,
+
+ PPI_CH_MAX
+} nrf_libuarte_ppi_channel_t;
+
+typedef enum
+{
+ PPI_GROUP_ENDRX_STARTRX,
+ PPI_GROUP_ENDRX_EXT_RXDONE_TSK,
+ PPI_GROUP_MAX
+} nrf_libuarte_ppi_group_t;
+
+static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(NRF_LIBUARTE_CONFIG_TIMER_USED);
+
+#if CONCAT_3(NRFX_TIMER, NRF_LIBUARTE_CONFIG_TIMER_USED,_ENABLED) == 0
+#error "Timer instance not enabled"
+#endif
+
+static nrf_ppi_channel_t m_ppi_channels[PPI_CH_MAX];
+static nrf_ppi_channel_group_t m_ppi_groups[PPI_GROUP_MAX];
+
+static uint8_t * mp_tx;
+static size_t m_tx_len;
+static size_t m_tx_cur_idx;
+
+static uint8_t * mp_cur_rx;
+static uint8_t * mp_next_rx;
+static uint8_t * mp_next_next_rx;
+static nrf_libuarte_evt_handler_t m_evt_handler;
+static uint32_t m_last_rx_byte_cnt;
+static uint32_t m_last_pin_rx_byte_cnt;
+static uint8_t m_tx_chunk8;
+static uint32_t m_chunk_size;
+
+#define PPI_CH_SETUP(_ch, _evt, _tsk, _fork) \
+ ret = nrfx_ppi_channel_assign(m_ppi_channels[_ch], _evt, _tsk); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ if (_fork) \
+ { \
+ ret = nrfx_ppi_channel_fork_assign(m_ppi_channels[_ch], _fork); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ }
+
+#define PPI_GROUP_SETUP(_ch, _group, _en_tsk, _dis_tsk) \
+ ret = nrfx_ppi_channel_include_in_group(m_ppi_channels[_ch], \
+ m_ppi_groups[_group]); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ _en_tsk = nrfx_ppi_task_addr_group_enable_get(m_ppi_groups[_group]); \
+ _dis_tsk = nrfx_ppi_task_addr_group_disable_get(m_ppi_groups[_group]);
+
+
+static ret_code_t ppi_configure(nrf_libuarte_config_t * p_config)
+{
+ ret_code_t ret;
+
+/*lint -save -e666 */
+
+ ///////////////////////////////////////////////////////////////////////////////
+ uint32_t group1_en_tsk;
+ uint32_t group1_dis_tsk;
+
+ PPI_GROUP_SETUP(PPI_CH_ENDRX_STARTRX, PPI_GROUP_ENDRX_STARTRX, group1_en_tsk, group1_dis_tsk);
+
+ PPI_CH_SETUP(PPI_CH_ENDRX_STARTRX,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX),
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STARTRX),
+ nrfx_timer_capture_task_address_get(&m_timer, 0));
+
+
+ ///////////////////////////////////////////////////////////////////////////////
+ uint32_t group2_en_tsk;
+ uint32_t group2_dis_tsk;
+
+ PPI_GROUP_SETUP(PPI_CH_ENDRX_EXT_TSK, PPI_GROUP_ENDRX_EXT_RXDONE_TSK, group2_en_tsk, group2_dis_tsk);
+
+ PPI_CH_SETUP(PPI_CH_ENDRX_EXT_TSK,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX),
+ nrfx_timer_capture_task_address_get(&m_timer, 0),
+ p_config->rxdone_tsk);
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX,
+ p_config->startrx_evt,
+ group1_en_tsk,
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STARTRX));
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_RXSTARTED_EXT_TSK,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED),
+ group2_dis_tsk,
+ p_config->rxstarted_tsk);
+
+ if (p_config->endrx_evt)
+ {
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_EXT_STOP_STOPRX,
+ p_config->endrx_evt,
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STOPRX),
+ group2_en_tsk);
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_EXT_STOP_GROUPS_EN,
+ p_config->endrx_evt,
+ group1_dis_tsk,
+ nrfx_timer_capture_task_address_get(&m_timer, 1));
+ }
+
+ ////////////////////////////////TX///////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_ENDTX_STARTTX,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDTX),
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STARTTX),
+ 0);
+
+ ////////////////////////////////TX///////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_RXRDY_TIMER_COUNT,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_RXDRDY),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_COUNT),
+ 0);
+
+ if (ret != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ return NRF_SUCCESS;
+/*lint -restore */
+}
+
+void tmr_evt_handler(nrf_timer_event_t event_type, void * p_context)
+{
+ UNUSED_PARAMETER(event_type);
+ UNUSED_PARAMETER(p_context);
+}
+
+ret_code_t nrf_libuarte_init(nrf_libuarte_config_t * p_config, nrf_libuarte_evt_handler_t evt_handler)
+{
+ ret_code_t ret;
+ m_evt_handler = evt_handler;
+ mp_cur_rx = NULL;
+ mp_next_rx = NULL;
+ mp_next_next_rx = NULL;
+ mp_tx = NULL;
+
+ //UART init
+ nrf_gpio_pin_set(p_config->tx_pin);
+ nrf_gpio_cfg_output(p_config->tx_pin);
+ nrf_gpio_cfg_input(p_config->rx_pin, NRF_GPIO_PIN_NOPULL);
+ nrf_uarte_baudrate_set(UART_DRV_UARTE, p_config->baudrate);
+ nrf_uarte_configure(UART_DRV_UARTE, p_config->parity, p_config->hwfc);
+ nrf_uarte_txrx_pins_set(UART_DRV_UARTE, p_config->tx_pin, p_config->rx_pin);
+
+ if (p_config->hwfc == NRF_UARTE_HWFC_ENABLED)
+ {
+ if (p_config->cts_pin != NRF_UARTE_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_input(p_config->cts_pin, NRF_GPIO_PIN_NOPULL);
+ }
+ if (p_config->rts_pin != NRF_UARTE_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_pin_set(p_config->rts_pin);
+ nrf_gpio_cfg_output(p_config->rts_pin);
+ }
+ nrf_uarte_hwfc_pins_set(UART_DRV_UARTE, p_config->rts_pin, p_config->cts_pin);
+ }
+
+ nrf_uarte_int_enable(UART_DRV_UARTE, INTERRUPTS_MASK);
+
+ NVIC_SetPriority(UART_DRV_IRQn, p_config->irq_priority);
+ NVIC_ClearPendingIRQ(UART_DRV_IRQn);
+ NVIC_EnableIRQ(UART_DRV_IRQn);
+
+ nrf_uarte_enable(UART_DRV_UARTE);
+
+ nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG;
+ tmr_config.mode = NRF_TIMER_MODE_COUNTER;
+ tmr_config.bit_width = NRF_TIMER_BIT_WIDTH_32;
+ ret = nrfx_timer_init(&m_timer, &tmr_config, tmr_evt_handler);
+ if (ret != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ nrfx_timer_enable(&m_timer);
+ nrfx_timer_clear(&m_timer);
+ m_last_rx_byte_cnt = 0;
+ m_last_pin_rx_byte_cnt = 0;
+
+ uint32_t i;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_alloc(&m_ppi_channels[i]);
+ if (ret != NRFX_SUCCESS)
+ {
+ //we don't free already allocated channels, system is wrongly configured.
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ for (i = 0; i < PPI_GROUP_MAX; i++)
+ {
+ ret = nrfx_ppi_group_alloc(&m_ppi_groups[i]);
+ if (ret != NRFX_SUCCESS)
+ {
+ //we don't free already allocated channels, system is wrongly configured.
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return ppi_configure(p_config);
+}
+
+void nrf_libuarte_uninit(void)
+{
+ NVIC_DisableIRQ(UART_DRV_IRQn);
+ nrf_uarte_int_disable(UART_DRV_UARTE, 0xFFFFFFFF);
+ nrf_uarte_disable(UART_DRV_UARTE);
+
+ nrfx_timer_disable(&m_timer);
+ nrfx_timer_uninit(&m_timer);
+
+ uint32_t i;
+ ret_code_t ret;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_disable(m_ppi_channels[i]);
+ ASSERT(ret == NRFX_SUCCESS)
+ ret = nrfx_ppi_channel_free(m_ppi_channels[i]);
+ ASSERT(ret == NRFX_SUCCESS)
+ }
+
+ for (i = 0; i < PPI_GROUP_MAX; i++)
+ {
+ ret = nrfx_ppi_group_free(m_ppi_groups[i]);
+ ASSERT(ret == NRFX_SUCCESS)
+ }
+
+}
+
+ret_code_t nrf_libuarte_tx(uint8_t * p_data, size_t len)
+{
+ if (mp_tx)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ mp_tx = p_data;
+ m_tx_len = len;
+ m_tx_cur_idx = 0;
+ uint8_t first_chunk;
+
+ if (len <= MAX_DMA_XFER_LEN)
+ {
+ first_chunk = len;
+ m_tx_chunk8 = 0;
+ }
+ else
+ {
+ uint32_t num_of_chunks = CEIL_DIV(len, MAX_DMA_XFER_LEN);
+ m_tx_chunk8 = len/num_of_chunks;
+ first_chunk = m_tx_chunk8 + len%m_tx_chunk8;
+ }
+
+ NRF_LOG_DEBUG("Started TX total length:%d, first chunk:%d", len, first_chunk);
+ nrf_uarte_tx_buffer_set(UART_DRV_UARTE, p_data, first_chunk);
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED);
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STARTTX);
+
+ if (len > MAX_DMA_XFER_LEN)
+ {
+ while(nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED) == 0)
+ {
+ }
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED);
+ nrfx_err_t err = nrfx_ppi_channel_enable(m_ppi_channels[PPI_CH_ENDTX_STARTTX]);
+ if (err != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_uarte_tx_buffer_set(UART_DRV_UARTE, &p_data[first_chunk], m_tx_chunk8);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_libuarte_rx_start(uint8_t * p_data, size_t len, bool ext_trigger_en)
+{
+
+ m_chunk_size = len;
+
+ uint32_t i;
+ for (i = 0; i < PPI_CH_RX_MAX; i++)
+ {
+ nrfx_err_t err = nrfx_ppi_channel_enable(m_ppi_channels[i]);
+ if (err != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ ASSERT(len <= MAX_DMA_XFER_LEN);
+
+ if (p_data)
+ {
+ mp_cur_rx = p_data;
+ nrf_uarte_rx_buffer_set(UART_DRV_UARTE, p_data, len);
+ }
+
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX);
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED);
+ if (ext_trigger_en)
+ {
+ }
+ else
+ {
+
+ *(uint32_t *)nrfx_ppi_task_addr_group_enable_get(m_ppi_groups[PPI_GROUP_ENDRX_STARTRX]) = 1;
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STARTRX);
+ }
+ NRF_LOG_DEBUG("Start continues RX. Provided buffer:0x%08X", p_data);
+ return NRF_SUCCESS;
+}
+
+void nrf_libuarte_rx_buf_rsp(uint8_t * p_data, size_t len)
+{
+ if (mp_next_rx == NULL)
+ {
+ mp_next_rx = p_data;
+ NRF_LOG_DEBUG("RX buf response (next). Provided buffer:0x%08X", p_data);
+ nrf_uarte_rx_buffer_set(UART_DRV_UARTE, p_data, len);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("RX buf response (mp_next_rx not NULL:0x%08X), Provided buffer:0x%08X",
+ mp_next_rx,
+ p_data);
+ mp_next_next_rx = p_data;
+ }
+}
+
+void nrf_libuarte_rx_stop(void)
+{
+ uint32_t i;
+ for (i = 0; i < PPI_CH_RX_MAX; i++)
+ {
+ nrfx_err_t err = nrfx_ppi_channel_disable(m_ppi_channels[i]);
+ ASSERT(err == NRFX_SUCCESS);
+ }
+
+ NRF_LOG_DEBUG("RX stopped.");
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STOPRX);
+}
+
+void UART_DRV_IRQHandler(void)
+{
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_ERROR))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ERROR);
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_ERROR
+ };
+ m_evt_handler(&evt);
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED);
+
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_RX_BUF_REQ,
+ };
+ m_evt_handler(&evt);
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX);
+
+ uint32_t endrx_byte_cnt = nrfx_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL0);
+ uint32_t stop_byte_cnt = nrfx_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL1);
+
+ uint32_t dma_amount = endrx_byte_cnt - m_last_rx_byte_cnt;
+ uint32_t pin_amount = stop_byte_cnt - m_last_pin_rx_byte_cnt;
+ NRF_LOG_DEBUG("(evt) RX dma_cnt:%d, endrx_cnt:%d, stop_cnt:%d",
+ dma_amount,
+ endrx_byte_cnt,
+ stop_byte_cnt);
+ m_last_rx_byte_cnt = endrx_byte_cnt;
+ m_last_pin_rx_byte_cnt = stop_byte_cnt;
+
+ if (dma_amount || pin_amount)
+ {
+ uint32_t chunk0 = (dma_amount > m_chunk_size) ? m_chunk_size : dma_amount;
+ uint32_t chunk1 = dma_amount - chunk0;
+
+ NRF_LOG_DEBUG("RX END chunk0:%d, chunk1:%d, data[0]=%d %d",
+ chunk0,
+ chunk1,
+ mp_cur_rx[0],
+ mp_cur_rx[1]);
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_RX_DATA,
+ .data = {
+ .rxtx = {
+ .p_data = mp_cur_rx,
+ .length = chunk0
+ }
+ }
+ };
+ mp_cur_rx = mp_next_rx;
+ mp_next_rx = NULL;
+ if (mp_next_next_rx)
+ {
+ mp_next_rx = mp_next_next_rx;
+ mp_next_next_rx = NULL;
+ nrf_uarte_rx_buffer_set(UART_DRV_UARTE, mp_next_rx, m_chunk_size);
+ }
+ m_evt_handler(&evt);
+
+ if ( chunk1 ||
+ ((dma_amount == m_chunk_size) && (endrx_byte_cnt == stop_byte_cnt)))
+ {
+ NRF_LOG_WARNING("RX END Chunk1:%d", chunk1);
+
+ evt.data.rxtx.length = chunk1;
+ evt.data.rxtx.p_data = mp_cur_rx;
+
+ mp_cur_rx = mp_next_rx;
+ mp_next_rx = NULL;
+ m_evt_handler(&evt);
+ }
+ }
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTOPPED))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTOPPED);
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_TX_DONE,
+ .data = {
+ .rxtx = {
+ .p_data = mp_tx,
+ .length = m_tx_len
+ }
+ }
+ };
+ mp_tx = NULL;
+ m_evt_handler(&evt);
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDTX))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDTX);
+ uint8_t amount = nrf_uarte_tx_amount_get(UART_DRV_UARTE);
+ NRF_LOG_DEBUG("(evt) TX completed (%d)", amount);
+ m_tx_cur_idx += amount;
+ if (m_tx_cur_idx == m_tx_len)
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTOPPED);
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STOPTX);
+ }
+ else
+ {
+ size_t rem_len = (m_tx_len - m_tx_cur_idx);
+ if ( rem_len <= MAX_DMA_XFER_LEN)
+ {
+ nrfx_err_t err = nrfx_ppi_channel_disable(m_ppi_channels[PPI_CH_ENDTX_STARTTX]);
+ ASSERT(err == NRFX_SUCCESS);
+ }
+ else
+ {
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED) == 0)
+ {
+ NRF_LOG_ERROR("Tx not started yet!");
+ ASSERT(false);
+ }
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED);
+ nrf_uarte_tx_buffer_set(UART_DRV_UARTE, &mp_tx[m_tx_cur_idx + m_tx_chunk8], m_tx_chunk8);
+ }
+ }
+
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h
new file mode 100644
index 0000000..0c9d97b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LIBUARTE_H
+#define NRF_LIBUARTE_H
+
+#include "sdk_errors.h"
+#include "nrf_uarte.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * @defgroup nrf_libuarte libUARTE
+ * @ingroup app_common
+ *
+ * @brief Module for reliable communication over UARTE.
+ *
+ * @{
+ */
+
+typedef enum
+{
+ NRF_LIBUARTE_EVT_RX_DATA, ///< Data received.
+ NRF_LIBUARTE_EVT_RX_BUF_REQ, ///< Requesting new buffer for receiving data.
+ NRF_LIBUARTE_EVT_TX_DONE, ///< Requested TX transfer completed.
+ NRF_LIBUARTE_EVT_ERROR ///< Error reported by the UARTE peripheral.
+} nrf_libuarte_evt_type_t;
+
+typedef struct
+{
+ uint8_t * p_data; ///< Pointer to the data to be sent or received.
+ size_t length; ///< Length of the data.
+} nrf_libuarte_data_t;
+
+typedef struct
+{
+ nrf_libuarte_evt_type_t type; ///< Event type.
+ union {
+ nrf_libuarte_data_t rxtx; ///< Data provided for transfer completion events.
+ } data;
+} nrf_libuarte_evt_t;
+
+typedef struct {
+ uint32_t tx_pin; ///< TXD pin number.
+ uint32_t rx_pin; ///< RXD pin number.
+ uint32_t cts_pin; ///< CTS pin number.
+ uint32_t rts_pin; ///< RTS pin number.
+ uint32_t startrx_evt; ///< Event to trigger STARTRX task in UARTE.
+ uint32_t endrx_evt; ///< Event to trigger STOPRX task in UARTE.
+ uint32_t rxstarted_tsk; ///< Task to be triggered when RXSTARTED UARTE event occurs.
+ uint32_t rxdone_tsk; ///< Task to be triggered when ENDRX UARTE event occurs.
+ nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uarte_parity_t parity; ///< Parity configuration.
+ nrf_uarte_baudrate_t baudrate; ///< Baud rate.
+ uint8_t irq_priority; ///< Interrupt priority.
+} nrf_libuarte_config_t;
+
+typedef void (*nrf_libuarte_evt_handler_t)(nrf_libuarte_evt_t * p_evt);
+
+/**
+ * @brief Function for initializing the libUARTE library.
+ *
+ * @param[in] p_config Pointer to the structure with initial configuration.
+ * @param[in] evt_handler Event handler provided by the user. Must not be NULL.
+ *
+ * @return NRF_SUCCESS when properly initialized. NRF_ERROR_INTERNAL otherwise.
+ */
+ret_code_t nrf_libuarte_init(nrf_libuarte_config_t * p_config, nrf_libuarte_evt_handler_t evt_handler);
+
+/** @brief Function for uninitializing the libUARTE library. */
+void nrf_libuarte_uninit(void);
+
+/**
+ * @brief Function for sending data over UARTE using EasyDMA.
+ *
+ * @param[in] p_data Pointer to data.
+ * @param[in] len Number of bytes to send.
+ *
+ * @retval NRF_ERROR_BUSY Data is transferring.
+ * @retval NRF_ERROR_INTERNAL Error during PPI channel configuration.
+ * @retval NRF_SUCCESS Buffer set for sending.
+ */
+ret_code_t nrf_libuarte_tx(uint8_t * p_data, size_t len);
+
+/**
+ * @brief Function for starting receiving data with additional configuration of external
+ * trigger to start receiving.
+ *
+ * @param p_data Pointer to data.
+ * @param len Number of bytes to receive. Maximum possible length is
+ * dependent on the used SoC (see the MAXCNT register
+ * description in the Product Specification). The library
+ * checks it with an assertion.
+ * @param ext_trigger_en True to disable immediate start.
+ *
+ * @retval NRF_ERROR_INTERNAL Error during PPI channel configuration.
+ * @retval NRF_SUCCESS Buffer set for receiving.
+ */
+ret_code_t nrf_libuarte_rx_start(uint8_t * p_data, size_t len, bool ext_trigger_en);
+
+/**
+ * @brief Function for setting a buffer for data that will be later received in UARTE.
+ *
+ * @param p_data Pointer to data.
+ * @param len Number of bytes to receive. Maximum possible length is
+ * dependent on the used SoC (see the MAXCNT register
+ * description in the Product Specification). The library
+ * checks it with an assertion.
+ */
+void nrf_libuarte_rx_buf_rsp(uint8_t * p_data, size_t len);
+
+/** @brief Function for stopping receiving data over UARTE. */
+void nrf_libuarte_rx_stop(void);
+
+/** @} */
+
+#endif //NRF_libuarte_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c
new file mode 100644
index 0000000..5c5a639
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_libuarte_async.h"
+#include "nrf_libuarte.h"
+#include "app_error.h"
+#include "nrf_balloc.h"
+#include "nrfx_timer.h"
+#include "nrfx_ppi.h"
+#include "nrf_uart.h"
+#include "nrf_queue.h"
+
+#define NRF_LOG_MODULE_NAME libUARTE_async
+#if NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#else // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static nrf_libuarte_async_evt_handler m_evt_handler;
+#define POOL_SZ 3UL
+#define MAX_CHUNK_SZ 255UL
+
+NRF_BALLOC_DEF(m_rx_pool, MAX_CHUNK_SZ, POOL_SZ);
+
+NRF_QUEUE_DEF(uint8_t *, m_rxdata_queue, 3, NRF_QUEUE_MODE_NO_OVERFLOW);
+
+#define UART_DRV_TIMER CONCAT_2(NRF_TIMER, NRF_LIBUARTE_CONFIG_TIMER_USED)
+#define UART_DRV_UARTE CONCAT_2(NRF_UARTE, NRF_LIBUARTE_CONFIG_UARTE_USED)
+
+static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(NRF_LIBUARTE_ASYNC_CONFIG_TIMER_USED);
+
+#if CONCAT_3(NRFX_TIMER, NRF_LIBUARTE_ASYNC_CONFIG_TIMER_USED,_ENABLED) == 0
+#error "Timer instance not enabled"
+#endif
+
+typedef enum
+{
+ PPI_CH_RXRDY_CLEAR,
+ PPI_CH_COMPARE_SHUTDOWN,
+ PPI_CH_MAX
+} nrf_libuarte_async_ppi_channel_t;
+
+static nrf_ppi_channel_t m_ppi_channels[PPI_CH_MAX];
+static int32_t m_alloc_cnt;
+static uint32_t m_rx_count;
+static uint32_t m_sub_rx_count;
+static uint8_t * mp_curr_rx_buf;
+static uint32_t m_rx_free_cnt;
+static size_t m_rx_chunk_size;
+
+#define PPI_CH_SETUP(_ch, _evt, _tsk, _fork) \
+ ret = nrfx_ppi_channel_assign(m_ppi_channels[_ch], _evt, _tsk); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ if (_fork) \
+ { \
+ ret = nrfx_ppi_channel_fork_assign(m_ppi_channels[_ch], _fork); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ }
+
+static void uart_evt_handler(nrf_libuarte_evt_t * p_evt)
+{
+ ret_code_t ret;
+ switch (p_evt->type)
+ {
+ case NRF_LIBUARTE_EVT_TX_DONE:
+ {
+ NRF_LOG_DEBUG("(evt) TX completed (%d)", p_evt->data.rxtx.length);
+ nrf_libuarte_async_evt_t evt = {
+ .type = NRF_LIBUARTE_ASYNC_EVT_TX_DONE,
+ .data.rxtx.p_data = p_evt->data.rxtx.p_data,
+ .data.rxtx.length = p_evt->data.rxtx.length,
+ };
+ m_evt_handler(&evt);
+ break;
+ }
+ case NRF_LIBUARTE_EVT_RX_BUF_REQ:
+ {
+ uint8_t * p_data = nrf_balloc_alloc(&m_rx_pool);
+ if (p_data)
+ {
+ ret = nrf_queue_push(&m_rxdata_queue, &p_data);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("(evt) RX buffer queue full.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ m_alloc_cnt++;
+ nrf_libuarte_rx_buf_rsp(p_data, m_rx_chunk_size);
+ }
+ else
+ {
+ NRF_LOG_ERROR("(evt) Failed to allocate buffer for RX.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+ case NRF_LIBUARTE_EVT_RX_DATA:
+ {
+
+ uint32_t rx_amount = p_evt->data.rxtx.length - m_sub_rx_count;
+ if (rx_amount)
+ {
+ m_rx_count += rx_amount;
+ nrf_libuarte_async_evt_t evt = {
+ .type = NRF_LIBUARTE_ASYNC_EVT_RX_DATA,
+ .data.rxtx.p_data = &p_evt->data.rxtx.p_data[m_sub_rx_count],
+ .data.rxtx.length = rx_amount,
+ };
+ NRF_LOG_DEBUG("(evt) RX: %d (addr:0x%08X, internal index: %d)",
+ rx_amount,
+ p_evt->data.rxtx.p_data,
+ m_sub_rx_count);
+
+ m_sub_rx_count = 0;
+
+ if(p_evt->data.rxtx.p_data != mp_curr_rx_buf)
+ {
+ NRF_LOG_ERROR("(evt) RX buffer address mismatch");
+ }
+
+ ret = nrf_queue_pop(&m_rxdata_queue, &mp_curr_rx_buf);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("RX buffer queue empty.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ m_evt_handler(&evt);
+ }
+ else
+ {
+ NRF_LOG_ERROR("(evt) RX with 0 length: 0x%08X", p_evt->data.rxtx.p_data);
+ //zero length packet is freed immediately and not forwarded to the application.
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+ default:
+ APP_ERROR_CHECK_BOOL(false);
+ break;
+ }
+}
+
+static void tmr_evt_handler(nrf_timer_event_t event_type, void * p_context)
+{
+ uint32_t capt_rx_count = UART_DRV_TIMER->CC[2];
+
+ if (capt_rx_count > m_rx_count)
+ {
+ uint32_t rx_amount = capt_rx_count - m_rx_count;
+ nrf_libuarte_async_evt_t evt = {
+ .type = NRF_LIBUARTE_ASYNC_EVT_RX_DATA,
+ .data.rxtx.p_data = &mp_curr_rx_buf[m_sub_rx_count],
+ .data.rxtx.length = rx_amount,
+ };
+ NRF_LOG_DEBUG("(tmr evt) RX: %d (addr:0x%08X, internal index: %d)",
+ rx_amount,
+ evt.data.rxtx.p_data,
+ m_sub_rx_count);
+
+ m_sub_rx_count += rx_amount;
+ m_rx_count = capt_rx_count;
+ m_evt_handler(&evt);
+ }
+}
+
+ret_code_t nrf_libuarte_async_init(nrf_libuarte_async_config_t const * p_config, nrf_libuarte_async_evt_handler evt_handler)
+{
+ ret_code_t ret;
+
+ m_evt_handler = evt_handler;
+ m_rx_count = 0;
+ mp_curr_rx_buf = NULL;
+ m_rx_free_cnt = 0;
+ m_sub_rx_count = 0;
+ m_alloc_cnt = 0;
+
+ nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG;
+ tmr_config.frequency = NRF_TIMER_FREQ_1MHz;
+ ret = nrfx_timer_init(&m_timer, &tmr_config, tmr_evt_handler);
+ if (ret != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ nrfx_timer_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, p_config->timeout_us, true);
+
+ uint32_t i;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_alloc(&m_ppi_channels[i]);
+ if (ret != NRFX_SUCCESS)
+ {
+ //we don't free already allocated channels, system is wrongly configured.
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+/*lint -save -e666 */
+ PPI_CH_SETUP(m_ppi_channels[PPI_CH_RXRDY_CLEAR],
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_RXDRDY),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_START),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_CLEAR));
+
+ PPI_CH_SETUP(m_ppi_channels[PPI_CH_COMPARE_SHUTDOWN],
+ nrfx_timer_compare_event_address_get(&m_timer, 0),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_SHUTDOWN),
+ (uint32_t)&UART_DRV_TIMER->TASKS_CAPTURE[2]);
+
+/*lint -restore */
+
+ nrf_libuarte_config_t uart_config = {
+ .tx_pin = p_config->tx_pin,
+ .rx_pin = p_config->rx_pin,
+ .cts_pin = p_config->cts_pin,
+ .rts_pin = p_config->rts_pin,
+ .startrx_evt = nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX),
+ .endrx_evt = 0,
+ .rxstarted_tsk = 0,
+ .rxdone_tsk = 0,
+ .hwfc = p_config->hwfc,
+ .parity = p_config->parity,
+ .baudrate = p_config->baudrate,
+ .irq_priority = 7,
+ };
+
+ ret = nrf_libuarte_init(&uart_config, uart_evt_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ ret = nrf_balloc_init(&m_rx_pool);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_queue_reset(&m_rxdata_queue);
+
+ return ret;
+}
+
+void nrf_libuarte_async_uninit(void)
+{
+ nrfx_err_t err = nrfx_ppi_channel_disable(m_ppi_channels[PPI_CH_RXRDY_CLEAR]);
+ APP_ERROR_CHECK_BOOL(err == NRFX_SUCCESS);
+ nrf_libuarte_uninit();
+ nrfx_timer_disable(&m_timer);
+ nrfx_timer_uninit(&m_timer);
+
+ uint32_t i;
+ ret_code_t ret;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_disable(m_ppi_channels[i]);
+ ASSERT(ret == NRF_SUCCESS)
+ ret = nrfx_ppi_channel_free(m_ppi_channels[i]);
+ ASSERT(ret == NRF_SUCCESS)
+ }
+}
+
+void nrf_libuarte_async_enable(size_t chunk_size)
+{
+ ASSERT(chunk_size <= MAX_CHUNK_SZ);
+ uint8_t * p_data;
+ p_data = nrf_balloc_alloc(&m_rx_pool);
+ m_alloc_cnt++;
+ if (p_data == NULL)
+ {
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ nrfx_timer_clear(&m_timer);
+ nrfx_err_t err = nrfx_ppi_channel_enable(m_ppi_channels[PPI_CH_RXRDY_CLEAR]);
+ APP_ERROR_CHECK_BOOL(err == NRFX_SUCCESS);
+ err = nrfx_ppi_channel_enable(m_ppi_channels[PPI_CH_COMPARE_SHUTDOWN]);
+ APP_ERROR_CHECK_BOOL(err == NRFX_SUCCESS);
+
+ mp_curr_rx_buf = p_data;
+ m_rx_chunk_size = chunk_size;
+ ret_code_t ret = nrf_libuarte_rx_start(p_data, chunk_size, false);
+ APP_ERROR_CHECK_BOOL(ret == NRF_SUCCESS);
+}
+
+ret_code_t nrf_libuarte_async_tx(uint8_t * p_data, size_t length)
+{
+ return nrf_libuarte_tx(p_data, length);
+}
+
+void nrf_libuarte_async_rx_free(uint8_t * p_data, size_t length)
+{
+ m_rx_free_cnt += length;
+ if (m_rx_free_cnt == m_rx_chunk_size)
+ {
+ p_data -= (m_rx_free_cnt - length);
+ m_rx_free_cnt = 0;
+ nrf_balloc_free(&m_rx_pool, p_data);
+
+ m_alloc_cnt--;
+ if (m_alloc_cnt<0)
+ {
+ NRF_LOG_ERROR("Freeing more RX buffers than allocated.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ NRF_LOG_INFO("Freeing full buffer 0x%08X, %d, (currently allocated:%d).",p_data, length, m_alloc_cnt);
+ }
+ else if (m_rx_free_cnt > m_rx_chunk_size)
+ {
+ NRF_LOG_ERROR("Unexpected RX free input parameter.")
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ else
+ {
+ NRF_LOG_INFO("Freeing partial buffer: 0x%08X, length:%d", p_data, length)
+ }
+
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h
new file mode 100644
index 0000000..9930a81
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef UART_ASYNC_H
+#define UART_ASYNC_H
+#include <stdint.h>
+#include "sdk_errors.h"
+#include <hal/nrf_uarte.h>
+
+/** @brief Types of libuarte driver events. */
+typedef enum
+{
+ NRF_LIBUARTE_ASYNC_EVT_RX_DATA, ///< Requested TX transfer completed.
+ NRF_LIBUARTE_ASYNC_EVT_TX_DONE, ///< Requested RX transfer completed.
+ NRF_LIBUARTE_ASYNC_EVT_ERROR ///< Error reported by UARTE peripheral.
+} nrf_libuarte_async_evt_type_t;
+
+/** @brief Structure for libuarte async transfer completion event. */
+typedef struct
+{
+ uint8_t * p_data; ///< Pointer to memory used for transfer.
+ size_t length; ///< Number of bytes transfered.
+} nrf_libuarte_async_data_t;
+
+/** @brief Structure for libuarte async configuration. */
+typedef struct
+{
+ uint32_t rx_pin; ///< RXD pin number.
+ uint32_t tx_pin; ///< TXD pin number.
+ uint32_t cts_pin; ///< CTS pin number.
+ uint32_t rts_pin; ///< RTS pin number.
+ uint32_t timeout_us; ///< Receiver timeout in us unit.
+ nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uarte_parity_t parity; ///< Parity configuration.
+ nrf_uarte_baudrate_t baudrate; ///< Baudrate.
+} nrf_libuarte_async_config_t;
+
+/** @brief Structure for libuarte error event. */
+typedef struct
+{
+ nrf_libuarte_async_evt_type_t type; ///< Event type.
+ union {
+ nrf_libuarte_async_data_t rxtx; ///< RXD/TXD data.
+ } data; ///< Union with data.
+} nrf_libuarte_async_evt_t;
+
+/**
+ * @brief Interrupt event handler.
+ *
+ * @param[in] p_evt Pointer to event structure. Event is allocated on the stack so it is available
+ * only within the context of the event handler.
+ */
+typedef void (*nrf_libuarte_async_evt_handler)(nrf_libuarte_async_evt_t * p_evt);
+
+/**
+ * @brief Function for initializing the libuarte async library.
+ *
+ * @param[in] p_config Pointer to the structure with initial configuration.
+ * @param[in] evt_handler Event handler provided by the user. Must not be NULL.
+ *
+ * @return NRF_SUCCESS when properly initialized. NRF_ERROR_INTERNAL otherwise.
+ */
+ret_code_t nrf_libuarte_async_init(nrf_libuarte_async_config_t const * p_config,
+ nrf_libuarte_async_evt_handler evt_handler);
+
+/** @brief Function for uninitializing the libuarte async library */
+void nrf_libuarte_async_uninit(void);
+
+/**
+ * @brief Funtrion for setting buffer and its size for received data.
+ *
+ * @param chunk_size Number of bytes in chunk of data
+ */
+void nrf_libuarte_async_enable(size_t chunk_size);
+
+/**
+ * @brief Function for sending data asynchronously over UARTE.
+ *
+ * @param[in] p_data Pointer to data.
+ * @param[in] length Number of bytes to send. Maximum possible length is
+ * dependent on the used SoC (see the MAXCNT register
+ * description in the Product Specification). The library
+ * checks it with assertion.
+ *
+ * @retval NRF_ERROR_BUSY Data is transferring.
+ * @retval NRF_ERROR_INTERNAL Error during configuration.
+ * @retval NRF_SUCCESS Buffer set for sending.
+ */
+ret_code_t nrf_libuarte_async_tx(uint8_t * p_data, size_t length);
+
+/**
+ * @brief Function for deallocating received buffer data.
+ *
+ * @param[in] p_data Pointer to data.
+ * @param[in] length Number of bytes to free.
+ */
+void nrf_libuarte_async_rx_free(uint8_t * p_data, size_t length);
+
+#endif //UART_ASYNC_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h
new file mode 100644
index 0000000..d709d23
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h
@@ -0,0 +1,291 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_log Logger module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief The nrf_log module interface.
+ */
+
+#ifndef NRF_LOG_H_
+#define NRF_LOG_H_
+
+#include "sdk_common.h"
+#include "nrf_section.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_strerror.h"
+#define NRF_LOG_ERROR_STRING_GET(code) nrf_strerror_get(code)
+#else
+#define NRF_LOG_ERROR_STRING_GET(code) ""
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Severity level for the module.
+ *
+ * The severity level can be defined in a module to override the default.
+ */
+#ifndef NRF_LOG_LEVEL
+ #define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL
+#endif
+
+/** @brief Initial severity if filtering is enabled.
+ */
+#ifndef NRF_LOG_INITIAL_LEVEL
+ #define NRF_LOG_INITIAL_LEVEL NRF_LOG_LEVEL
+#endif
+
+
+#include "nrf_log_internal.h"
+
+/** @def NRF_LOG_ERROR
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_WARNING
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
+ */
+
+/** @def NRF_LOG_INFO
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
+ */
+
+/** @def NRF_LOG_DEBUG
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
+ */
+
+#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__)
+#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__)
+#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__)
+#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__)
+
+/** @def NRF_LOG_INST_ERROR
+ * @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_INST_WARNING
+ * @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_INST_INFO
+ * @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_INST_DEBUG
+ * @brief Macro for logging error messages for given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+#define NRF_LOG_INST_ERROR(p_inst,...) NRF_LOG_INTERNAL_INST_ERROR(p_inst,__VA_ARGS__)
+#define NRF_LOG_INST_WARNING(p_inst,...) NRF_LOG_INTERNAL_INST_WARNING(p_inst,__VA_ARGS__)
+#define NRF_LOG_INST_INFO(p_inst,...) NRF_LOG_INTERNAL_INST_INFO(p_inst, __VA_ARGS__)
+#define NRF_LOG_INST_DEBUG(p_inst,...) NRF_LOG_INTERNAL_INST_DEBUG(p_inst, __VA_ARGS__)
+
+/**
+ * @brief Macro for logging a formatted string without any prefix or timestamp.
+ */
+#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__)
+
+/** @def NRF_LOG_HEXDUMP_ERROR
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_WARNING
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INFO
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_DEBUG
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len)
+#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len)
+#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len)
+#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len)
+
+/** @def NRF_LOG_HEXDUMP_INST_ERROR
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INST_WARNING
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INST_INFO
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INST_DEBUG
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+#define NRF_LOG_HEXDUMP_INST_ERROR(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len)
+#define NRF_LOG_HEXDUMP_INST_WARNING(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len)
+#define NRF_LOG_HEXDUMP_INST_INFO(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len)
+#define NRF_LOG_HEXDUMP_INST_DEBUG(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len)
+
+/**
+ * @brief Macro for logging hexdump without any prefix or timestamp.
+ */
+#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len)
+
+
+/**
+ * @brief Macro for copying a string to internal logger buffer if logs are deferred.
+ *
+ * @param _str String.
+ */
+#define NRF_LOG_PUSH(_str) NRF_LOG_INTERNAL_LOG_PUSH(_str)
+
+/**
+ * @brief Function for copying a string to the internal logger buffer if logs are deferred.
+ *
+ * Use this function to store a string that is volatile (for example allocated
+ * on stack) or that may change before the deferred logs are processed. Such string is copied
+ * into the internal logger buffer and is persistent until the log is processed.
+ *
+ * @note If the logs are not deferred, then this function returns the input parameter.
+ *
+ * @param p_str Pointer to the user string.
+ *
+ * @return Address to the location where the string is stored in the internal logger buffer.
+ */
+uint32_t nrf_log_push(char * const p_str);
+
+/**
+ * @brief Macro to be used in a formatted string to a pass float number to the log.
+ *
+ * Use this macro in a formatted string instead of the %f specifier together with
+ * @ref NRF_LOG_FLOAT macro.
+ * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
+ */
+#define NRF_LOG_FLOAT_MARKER "%s%d.%02d"
+
+/**
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).
+ */
+#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""), \
+ (int32_t)(val), \
+ (int32_t)((((val) > 0) ? (val) - (int32_t)(val) \
+ : (int32_t)(val) - (val))*100)
+
+
+/**
+ * @brief Macro for registering an independent module.
+ *
+ * Registration creates set of dynamic (RAM) and constant variables associated with the module.
+ */
+#define NRF_LOG_MODULE_REGISTER() NRF_LOG_INTERNAL_MODULE_REGISTER()
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_LOG_H_
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h
new file mode 100644
index 0000000..c93ae35
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /**@file
+ *
+ * @defgroup nrf_log_backend_flash Flash logger backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Flash logger backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_FLASH_H
+#define NRF_LOG_BACKEND_FLASH_H
+
+#include "nrf_log_backend_interface.h"
+#include "nrf_fstorage.h"
+#include "nrf_log_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Flashlog logger backend API. */
+extern const nrf_log_backend_api_t nrf_log_backend_flashlog_api;
+
+/** @brief Crashlog logger backend API. */
+extern const nrf_log_backend_api_t nrf_log_backend_crashlog_api;
+
+/** @brief Flashlog logger backend structure. */
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_flashlog_t;
+
+/** @brief Crashlog logger backend structure. */
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_crashlog_t;
+
+/** @brief Macro for creating an instance of the flashlog logger backend. */
+#define NRF_LOG_BACKEND_FLASHLOG_DEF(name) \
+ static nrf_log_backend_flashlog_t name = { \
+ .backend = {.p_api = &nrf_log_backend_flashlog_api}, \
+ }
+
+/** @brief Macro for creating an instance of the crashlog logger backend. */
+#define NRF_LOG_BACKEND_CRASHLOG_DEF(name) \
+ static nrf_log_backend_crashlog_t name = { \
+ .backend = {.p_api = &nrf_log_backend_crashlog_api}, \
+ }
+
+/**
+ * @brief Function for initializing the flash logger backend.
+ *
+ * Flash logger backend consists of two logical backends: flashlog and crashlog. Since both
+ * backends write to the same flash area, the initialization is common.
+ *
+ * @param p_fs_api fstorage API to be used.
+ *
+ * @return NRF_SUCCESS or error code returned by @ref nrf_fstorage_init.
+ */
+ret_code_t nrf_log_backend_flash_init(nrf_fstorage_api_t const * p_fs_api);
+
+/**
+ * @brief Function for getting a log entry stored in flash.
+ *
+ * Log messages stored in flash can be read one by one starting from the oldest one.
+ *
+ * @param[in, out] p_token Token reused between consecutive readings of log entries.
+ * Token must be set to 0 to read the first entry.
+ * @param[out] pp_header Pointer to the entry header.
+ * @param[out] pp_data Pointer to the data part of the entry (arguments or data in case of hexdump).
+ *
+ * @retval NRF_SUCCESS Entry was successfully read.
+ * @retval NRF_ERROR_NOT_SUPPORTED fstorage API does not support direct reading.
+ * @retval NRF_ERROR_NOT_FOUND Entry not found. Last entry was already reached or area is empty.
+ */
+ret_code_t nrf_log_backend_flash_next_entry_get(uint32_t * p_token,
+ nrf_log_header_t * * pp_header,
+ uint8_t * * pp_data);
+
+/**
+ * @brief Function for erasing flash area dedicated for the flash logger backend.
+ */
+ret_code_t nrf_log_backend_flash_erase(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_UART_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h
new file mode 100644
index 0000000..9d1af51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_BACKEND_INTERFACE_H
+#define NRF_LOG_BACKEND_INTERFACE_H
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_backend_interface Logger backend interface
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log backend interface.
+ */
+
+#include "nrf_memobj.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief nrf_log entry.
+ */
+typedef nrf_memobj_t nrf_log_entry_t;
+
+/* Forward declaration of the nrf_log_backend_t type. */
+typedef struct nrf_log_backend_s nrf_log_backend_t;
+
+/**
+ * @brief Logger backend API.
+ */
+typedef struct
+{
+ /**
+ * @brief @ref nrf_log_backend_put
+ */
+ void (*put)(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_entry);
+
+ /**
+ * @brief @ref nrf_log_backend_panic_set
+ */
+ void (*panic_set)(nrf_log_backend_t const * p_backend);
+
+ /**
+ * @brief @ref nrf_log_backend_flush
+ */
+ void (*flush)(nrf_log_backend_t const * p_backend);
+} nrf_log_backend_api_t;
+
+/**
+ * @brief Logger backend structure.
+ */
+struct nrf_log_backend_s
+{
+ nrf_log_backend_api_t const * p_api; //!< Pointer to interface.
+ nrf_log_backend_t * p_next; //!< Pointer to next backend added to the logger.
+ uint8_t id; //!< Backend id.
+ bool enabled;//!< Flag indicating backend status.
+};
+
+/**
+ * @brief Function for putting message with log entry to the backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @param[in] p_msg Pointer to message with log entry.
+ */
+__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg);
+
+/**
+ * @brief Function for reconfiguring backend to panic mode.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * p_backend);
+
+/**
+ * @brief Function for flushing backend.
+ *
+ * On flushing request backend should release log message(s).
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * p_backend);
+
+
+/**
+ * @brief Function for setting backend id.
+ *
+ * @note It is used internally by the logger.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @param[in] id Id.
+ */
+__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t * p_backend, uint8_t id);
+
+/**
+ * @brief Function for getting backend id.
+ *
+ * @note It is used internally by the logger.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @return Id.
+ */
+__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * p_backend);
+
+/**
+ * @brief Function for enabling backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for disabling backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for checking state of the backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ *
+ * @return True if backend is enabled, false otherwise.
+ */
+__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * p_backend);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ p_backend->p_api->put(p_backend, p_msg);
+}
+
+__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * p_backend)
+{
+ p_backend->p_api->panic_set(p_backend);
+}
+
+__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * p_backend)
+{
+ p_backend->p_api->flush(p_backend);
+}
+
+__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t * p_backend, uint8_t id)
+{
+ p_backend->id = id;
+}
+
+__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * p_backend)
+{
+ return p_backend->id;
+}
+
+__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t * p_backend)
+{
+ p_backend->enabled = true;
+}
+
+__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t * p_backend)
+{
+ p_backend->enabled = false;
+}
+
+__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * p_backend)
+{
+ return p_backend->enabled;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_INTERFACE_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h
new file mode 100644
index 0000000..efa1032
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /**@file
+ *
+ * @defgroup nrf_log_backend_rtt Log RTT backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Log RTT backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_RTT_H
+#define NRF_LOG_BACKEND_RTT_H
+
+#include "nrf_log_backend_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const nrf_log_backend_api_t nrf_log_backend_rtt_api;
+
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_rtt_t;
+
+/**
+ * @brief RTT backend definition
+ *
+ * @param _name Name of the instance.
+ */
+#define NRF_LOG_BACKEND_RTT_DEF(_name) \
+ static nrf_log_backend_rtt_t _name = { \
+ .backend = {.p_api = &nrf_log_backend_rtt_api}, \
+ }
+
+void nrf_log_backend_rtt_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_RTT_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h
new file mode 100644
index 0000000..2743e29
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /**@file
+ *
+ * @defgroup nrf_log_backend_uart Log UART backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Log UART backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_UART_H
+#define NRF_LOG_BACKEND_UART_H
+
+#include "nrf_log_backend_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const nrf_log_backend_api_t nrf_log_backend_uart_api;
+
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_uart_t;
+
+#define NRF_LOG_BACKEND_UART_DEF(name) \
+ static nrf_log_backend_uart_t name = { \
+ .backend = {.p_api = &nrf_log_backend_uart_api}, \
+ }
+
+void nrf_log_backend_uart_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_UART_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h
new file mode 100644
index 0000000..828f1f7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h
@@ -0,0 +1,226 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_CTRL_H
+#define NRF_LOG_CTRL_H
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_ctrl Functions for controlling nrf_log
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log control interface.
+ */
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log_types.h"
+#include "nrf_log_ctrl_internal.h"
+#include "nrf_log_backend_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Timestamp function prototype.
+ *
+ * @return Timestamp value.
+ */
+typedef uint32_t (*nrf_log_timestamp_func_t)(void);
+
+/**@brief Macro for initializing the logs.
+ *
+ * Macro has one or two parameters. First parameter (obligatory) is the timestamp function (@ref nrf_log_timestamp_func_t).
+ * Additionally, as the second parameter timestamp frequency in Hz can be provided. If not provided then default
+ * frequency is used (@ref NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY). Frequency is used to format timestamp prefix if
+ * @ref NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED is set.
+ *
+ * @return NRF_SUCCESS after successful initialization, otherwise an error code.
+ */
+#define NRF_LOG_INIT(...) NRF_LOG_INTERNAL_INIT(__VA_ARGS__)
+
+
+/**@brief Macro for processing a single log entry from a queue of deferred logs.
+ *
+ * You can call this macro from the main context or from the error handler to process
+ * log entries one by one.
+ *
+ * @note If logs are not deferred, this call has no use and is defined as 'false'.
+ *
+ * @retval true There are more logs to process in the buffer.
+ * @retval false No more logs in the buffer.
+ */
+#define NRF_LOG_PROCESS() NRF_LOG_INTERNAL_PROCESS()
+
+/** @brief Macro for processing all log entries from the buffer.
+ * It blocks until all buffered entries are processed by the backend.
+ *
+ * @note If logs are not deferred, this call has no use and is empty.
+ */
+#define NRF_LOG_FLUSH() NRF_LOG_INTERNAL_FLUSH()
+
+/** @brief Macro for flushing log data before reset.
+ *
+ * @note If logs are not deferred, this call has no use and is empty.
+ *
+ * @note If RTT is used, then a breakpoint is hit once flushed.
+ */
+#define NRF_LOG_FINAL_FLUSH() NRF_LOG_INTERNAL_FINAL_FLUSH()
+
+/**
+ * @brief Function for initializing the frontend and the default backend.
+ *
+ * @ref NRF_LOG_INIT calls this function to initialize the frontend and the backend.
+ * If custom backend is used, then @ref NRF_LOG_INIT should not be called.
+ * Instead, frontend and user backend should be verbosely initialized.
+ *
+ * @param timestamp_func Function for getting a 32-bit timestamp.
+ * @param timestamp_freq Frequency of the timestamp.
+ *
+ * @return Error status.
+ *
+ */
+ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq);
+
+/**
+ * @brief Function for adding new backend interface to the logger.
+ *
+ * @param p_backend Pointer to the backend interface.
+ * @param severity Initial value of severity level for each module forwarded to the backend. This
+ * option is only applicable if @ref NRF_LOG_FILTERS_ENABLED is set.
+ * @return -1 if backend cannot be added or positive number (backend ID).
+ */
+int32_t nrf_log_backend_add(nrf_log_backend_t * p_backend, nrf_log_severity_t severity);
+
+/**
+ * @brief Function for removing backend from the logger.
+ *
+ * @param p_backend Pointer to the backend interface.
+ *
+ */
+void nrf_log_backend_remove(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for setting logger backends into panic mode.
+ *
+ * When this function is called all attached backends are informed about panic state of the system.
+ * It is up to the backend to react properly (hold or process logs in blocking mode, etc.)
+ */
+void nrf_log_panic(void);
+
+/**
+ * @brief Function for handling a single log entry.
+ *
+ * Use this function only if the logs are buffered. It takes a single entry from the
+ * buffer and attempts to process it.
+ *
+ * @retval true If there are more entries to process.
+ * @retval false If there are no more entries to process.
+ */
+bool nrf_log_frontend_dequeue(void);
+
+/**
+ * @brief Function for getting number of independent log modules registered into the logger.
+ *
+ * @return Number of registered modules.
+ */
+uint32_t nrf_log_module_cnt_get(void);
+
+/**
+ * @brief Function for getting module name.
+ *
+ * @param module_id Module ID.
+ * @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
+ * @return Pointer to string with module name.
+ */
+const char * nrf_log_module_name_get(uint32_t module_id, bool is_ordered_idx);
+
+/**
+ * @brief Function for getting coloring of specific logs.
+ *
+ * @param module_id Module ID.
+ * @param severity Log severity.
+ *
+ * @return ID of the color.
+ */
+uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity);
+
+/**
+ * @brief Function for configuring filtering ofs logs in the module.
+ *
+ * Filtering of logs in modules is independent for each backend.
+ *
+ * @param backend_id Backend ID which want to chenge its configuration.
+ * @param module_id Module ID which logs will be reconfigured.
+ * @param severity New severity filter.
+ */
+void nrf_log_module_filter_set(uint32_t backend_id,
+ uint32_t module_id,
+ nrf_log_severity_t severity);
+
+/**
+ * @brief Function for getting module severity level.
+ *
+ * @param backend_id Backend ID.
+ * @param module_id Module ID.
+ * @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
+ * @param dynamic It true current filter for given backend is returned. If false then
+ * compiled-in level is returned (maximum available). If this parameter is
+ * false then backend_id parameter is not used.
+ *
+ * @return Severity.
+ */
+nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
+ uint32_t module_id,
+ bool is_ordered_idx,
+ bool dynamic);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_LOG_CTRL_H
+
+/**
+ *@}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h
new file mode 100644
index 0000000..8ad3da4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_DEFAULT_BACKENDS_H__
+#define NRF_LOG_DEFAULT_BACKENDS_H__
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_default_backends Functions for initializing and adding default backends
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log default backends.
+ */
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @def NRF_LOG_DEFAULT_BACKENDS_INIT
+ * @brief Macro for initializing default backends.
+ *
+ * Each backend enabled in configuration is initialized and added as a backend to the logger.
+ */
+#if NRF_LOG_ENABLED
+#define NRF_LOG_DEFAULT_BACKENDS_INIT() nrf_log_default_backends_init()
+#else
+#define NRF_LOG_DEFAULT_BACKENDS_INIT()
+#endif
+
+void nrf_log_default_backends_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // NRF_LOG_DEFAULT_BACKENDS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h
new file mode 100644
index 0000000..a4ba83d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_INSTANCE_H
+#define NRF_LOG_INSTANCE_H
+
+#include "sdk_config.h"
+#include "nrf_section.h"
+#include "nrf_log_types.h"
+#include <stdint.h>
+/*
+ * For GCC, sections are sorted in the group by the linker. For IAR and KEIL, it is assumed that linker will sort
+ * dynamic and const section in the same order (but in different locations). Proper message formatting
+ * is based on that assumption.
+ */
+#if defined(__GNUC__)
+#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) CONCAT_2(log_dynamic_data_,_module_name)
+#define NRF_LOG_CONST_SECTION_NAME(_module_name) CONCAT_2(log_const_data_,_module_name)
+#else
+#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) log_dynamic_data
+#define NRF_LOG_CONST_SECTION_NAME(_module_name) log_const_data
+#endif
+
+#define NRF_LOG_ITEM_DATA(_name) CONCAT_3(m_nrf_log_,_name,_logs_data)
+#define NRF_LOG_ITEM_DATA_DYNAMIC(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_dynamic)
+#define NRF_LOG_ITEM_DATA_CONST(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_const)
+
+#ifdef UNIT_TEST
+#define _CONST
+#else
+#define _CONST const
+#endif
+
+#if NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_DYNAMIC_STRUCT_NAME nrf_log_module_dynamic_data_t
+#else
+#define NRF_LOG_DYNAMIC_STRUCT_NAME nrf_log_module_reduced_dynamic_data_t
+#endif
+
+#define NRF_LOG_INTERNAL_ITEM_REGISTER( \
+ _name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
+ NRF_SECTION_ITEM_REGISTER(NRF_LOG_CONST_SECTION_NAME(_name), \
+ _CONST nrf_log_module_const_data_t NRF_LOG_ITEM_DATA_CONST(_name)) = { \
+ .p_module_name = _str_name, \
+ .info_color_id = (_info_color), \
+ .debug_color_id = (_debug_color), \
+ .compiled_lvl = (nrf_log_severity_t)(_compiled_lvl), \
+ .initial_lvl = (nrf_log_severity_t)(_initial_lvl), \
+ }; \
+ NRF_SECTION_ITEM_REGISTER(NRF_LOG_DYNAMIC_SECTION_NAME(_name), \
+ NRF_LOG_DYNAMIC_STRUCT_NAME NRF_LOG_ITEM_DATA_DYNAMIC(_name))
+
+/**@file
+ *
+ * @defgroup nrf_log_instance Macros for logging on instance level
+ * @{
+ * @ingroup nrf_log
+ *
+ * @brief Macros for logging on instance level
+ */
+
+/** @def NRF_LOG_INSTANCE_PTR_DECLARE
+ * @brief Macro for declaring a logger instance pointer in the module stucture.
+ */
+
+/** @def NRF_LOG_INSTANCE_REGISTER
+ * @brief Macro for creating an independent module instance.
+ *
+ * Module instance provides filtering of logs on instance level instead of module level.
+ */
+
+/** @def NRF_LOG_INSTANCE_PTR_INIT
+ * @brief Macro for initializing a pointer to the logger instance.
+ */
+
+
+ /** @} */
+#if NRF_LOG_ENABLED
+#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name) NRF_LOG_DYNAMIC_STRUCT_NAME * _p_name;
+
+#define NRF_LOG_INSTANCE_REGISTER( \
+ _module_name, _inst_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
+ NRF_LOG_INTERNAL_ITEM_REGISTER(CONCAT_3(_module_name,_,_inst_name), \
+ STRINGIFY(_module_name._inst_name), \
+ _info_color, \
+ _debug_color, \
+ _initial_lvl, \
+ _compiled_lvl)
+
+#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name) \
+ ._p_name = &NRF_LOG_ITEM_DATA_DYNAMIC(CONCAT_3(_module_name,_,_inst_name)),
+
+#else
+#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name)
+#define NRF_LOG_INSTANCE_REGISTER(_module_name, _inst_name, info_color, debug_color, _initial_lvl, compiled_lvl)
+#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name)
+#endif
+
+#endif //NRF_LOG_INSTANCE_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h
new file mode 100644
index 0000000..b651183
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**@file
+ *
+ * @defgroup nrf_log_str_formatter String formatter for the logger messages
+ * @{
+ * @ingroup nrf_log
+ */
+
+#ifndef NRF_LOG_STR_FORMATTER_H
+#define NRF_LOG_STR_FORMATTER_H
+
+#include <stdint.h>
+#include "nrf_fprintf.h"
+#include "nrf_log_ctrl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ uint32_t timestamp;
+ uint16_t module_id;
+ uint16_t dropped;
+ nrf_log_severity_t severity;
+ uint8_t use_colors;
+} nrf_log_str_formatter_entry_params_t;
+
+
+void nrf_log_std_entry_process(char const * p_str,
+ uint32_t const * p_args,
+ uint32_t nargs,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx);
+
+void nrf_log_hexdump_entry_process(uint8_t * p_data,
+ uint32_t data_len,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx);
+
+void nrf_log_str_formatter_timestamp_freq_set(uint32_t freq);
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_STR_FORMATTER_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h
new file mode 100644
index 0000000..2ae08d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_TYPES_H
+#define NRF_LOG_TYPES_H
+
+#include <stdint.h>
+
+/**
+ * @brief Logger severity levels.
+ */
+typedef enum
+{
+ NRF_LOG_SEVERITY_NONE,
+ NRF_LOG_SEVERITY_ERROR,
+ NRF_LOG_SEVERITY_WARNING,
+ NRF_LOG_SEVERITY_INFO,
+ NRF_LOG_SEVERITY_DEBUG,
+ NRF_LOG_SEVERITY_INFO_RAW, /* Artificial level to pass information about skipping string postprocessing.*/
+} nrf_log_severity_t;
+
+/**
+ * @brief Structure holding dynamic data associated with a module or instance if filtering is enabled (@ref NRF_LOG_FILTERS_ENABLED).
+ *
+ * See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
+ */
+typedef struct
+{
+ uint16_t module_id; ///< Module ID assigned during initialization.
+ uint16_t order_idx; ///< Ordered index of the module (used for auto-completion).
+ uint32_t filter; ///< Current highest severity level accepted (redundant to @ref nrf_log_module_dynamic_data_t::filter_lvls, used for optimization)
+ uint32_t filter_lvls; ///< Current severity levels for each backend (3 bits per backend).
+} nrf_log_module_dynamic_data_t;
+
+/**
+ * @brief Structure holding dynamic data associated with a module or instance if filtering is disabled (@ref NRF_LOG_FILTERS_ENABLED).
+ *
+ * See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
+ */
+typedef struct
+{
+ uint16_t module_id; ///< Module ID assigned during initialization.
+ uint16_t padding; ///< Padding to fit in word.
+} nrf_log_module_reduced_dynamic_data_t;
+
+
+/**
+ * @brief Structure holding constant data associated with a module or instance.
+ *
+ * See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
+ */
+typedef struct
+{
+ const char * p_module_name; ///< Module or instance name.
+ uint8_t info_color_id; ///< Color code of info messages.
+ uint8_t debug_color_id; ///< Color code of debug messages.
+ nrf_log_severity_t compiled_lvl; ///< Compiled highest severity level.
+ nrf_log_severity_t initial_lvl; ///< Severity level for given module or instance set on backend initialization.
+} nrf_log_module_const_data_t;
+
+#endif //NRF_LOG_TYPES_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c
new file mode 100644
index 0000000..0efd5d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c
@@ -0,0 +1,739 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_FLASH)
+#include "nrf_log_backend_flash.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_fstorage_nvmc.h"
+#include "nrf_log.h"
+#include "nrf_atomic.h"
+#include "nrf_queue.h"
+#include "app_error.h"
+#include <stdbool.h>
+
+#if (NRF_LOG_BACKEND_FLASHLOG_ENABLED == 0) && (NRF_LOG_BACKEND_CRASHLOG_ENABLED == 0)
+#error "No flash backend enabled."
+#endif
+
+/** @brief Maximum logger message payload (arguments or data in hexdump) which can be stored. */
+#define FLASH_LOG_MAX_PAYLOAD_SIZE (NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE - sizeof(nrf_log_header_t))
+
+/** @brief Size of serialization buffer in words. */
+#define FLASH_LOG_SER_BUFFER_WORDS (NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE/sizeof(uint32_t))
+
+/** @brief Length of logger header. */
+#define LOG_HEADER_LEN (sizeof(nrf_log_header_t))
+
+/** @brief Length of logger header given in 32 bit words. */
+#define LOG_HEADER_LEN_WORDS (LOG_HEADER_LEN/sizeof(uint32_t))
+
+/** @brief Maximum possible length of standard log message. */
+#define STD_LOG_MSG_MAX_LEN (LOG_HEADER_LEN + NRF_LOG_MAX_NUM_OF_ARGS*sizeof(uint32_t))
+
+/* Buffer must be multiple of 4. */
+STATIC_ASSERT((NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE % sizeof(uint32_t)) == 0);
+
+/* Buffer must fit standard log message. */
+STATIC_ASSERT(NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE >= STD_LOG_MSG_MAX_LEN);
+
+/** @brief Flash page size in bytes. */
+#define CODE_PAGE_SIZE 4096
+
+/** @brief Start address of the area dedicated for flash log. */
+#define FLASH_LOG_START_ADDR (NRF_LOG_BACKEND_FLASH_START_PAGE * CODE_PAGE_SIZE)
+
+/** @brief End address of the area dedicated for flash log. */
+#define FLASH_LOG_END_ADDR (FLASH_LOG_START_ADDR + (NRF_LOG_BACKEND_PAGES * CODE_PAGE_SIZE) - 1)
+
+/** @brief Size of the area dedicated for flash log. */
+#define FLASH_LOG_SIZE (NRF_LOG_BACKEND_PAGES * CODE_PAGE_SIZE)
+
+/** @brief Start address determined in runtime.
+ *
+ * If configuration indicates that flash log should be placed after application.
+ * */
+#if defined ( __CC_ARM )
+#define RUNTIME_START_ADDR \
+ _Pragma("diag_suppress 170") \
+ ((NRF_LOG_BACKEND_FLASH_START_PAGE == 0) ? \
+ (CODE_PAGE_SIZE*CEIL_DIV((uint32_t)CODE_END, CODE_PAGE_SIZE)) : FLASH_LOG_START_ADDR) \
+ _Pragma("diag_default 170")
+#else
+#define RUNTIME_START_ADDR ((NRF_LOG_BACKEND_FLASH_START_PAGE == 0) ? \
+ (CODE_PAGE_SIZE*CEIL_DIV((uint32_t)CODE_END, CODE_PAGE_SIZE)) : FLASH_LOG_START_ADDR)
+#endif
+static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);
+
+/** @brief Message queue for run time flash log. */
+#if NRF_LOG_BACKEND_FLASHLOG_ENABLED
+NRF_QUEUE_DEF(nrf_log_entry_t *,
+ m_flashlog_queue,
+ NRF_LOG_BACKEND_FLASHLOG_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+static const nrf_queue_t * mp_flashlog_queue = &m_flashlog_queue;
+#else
+static const nrf_queue_t * mp_flashlog_queue = NULL;
+#endif
+
+
+/** @brief Message FIFO for crash log. */
+#if NRF_LOG_BACKEND_CRASHLOG_ENABLED
+NRF_QUEUE_DEF(nrf_log_entry_t *,
+ m_crashlog_queue,
+ NRF_LOG_BACKEND_CRASHLOG_FIFO_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+static const nrf_queue_t * mp_crashlog_queue = &m_crashlog_queue;
+#else
+static const nrf_queue_t * mp_crashlog_queue = NULL;
+#endif
+
+
+/** @brief Fstorage instance used for flash log. */
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_log_flash_fstorage) =
+{
+ /* Set a handler for fstorage events. */
+ .evt_handler = fstorage_evt_handler,
+ .start_addr = FLASH_LOG_START_ADDR,
+ .end_addr = FLASH_LOG_END_ADDR,
+};
+
+/** @brief Flash log state. */
+typedef enum
+{
+ LOG_BACKEND_FLASH_ACTIVE, /**< Flash backend is active. */
+ LOG_BACKEND_FLASH_INACTIVE, /**< Flash backend is inactive. All incoming requests are skipped. */
+ LOG_BACKEND_FLASH_IN_PANIC, /**< Flash backend is in panic mode. Incoming messages are written to flash in synchronous mode. */
+} log_backend_flash_state_t;
+
+static log_backend_flash_state_t m_state; /**< Flash logger backend state. */
+static nrf_atomic_flag_t m_busy_flag; /**< Flag indicating if module performs flash writing. */
+static uint32_t m_flash_buf[FLASH_LOG_SER_BUFFER_WORDS]; /**< Buffer used for serializing messages. */
+static uint32_t m_curr_addr; /**< Address of free spot in the storage area. */
+static size_t m_curr_len; /**< Length of current message being written. */
+static uint32_t m_dropped; /**< Number of dropped messages. */
+
+/** @brief Log message string injected when entering panic mode. */
+static const char crashlog_str[] = "-----------CRASHLOG------------\r\n";
+
+/** @brief Function saturates input to maximum possible length and rounds up value to be multiple
+ * of word size.
+ *
+ * @param length Length value.
+ *
+ * @return Modified input length.
+ */
+static uint32_t saturate_align_length(uint32_t length)
+{
+ length = (length > FLASH_LOG_MAX_PAYLOAD_SIZE) ? FLASH_LOG_MAX_PAYLOAD_SIZE : length; //saturate
+ length = CEIL_DIV(length, sizeof(uint32_t))*sizeof(uint32_t);
+ return length;
+}
+
+
+/**
+ * @brief Function for copying logger message to the buffer.
+ *
+ * @param[in] p_msg Logger message.
+ * @param[out] p_buf Output buffer where serialized message is placed.
+ * @param[in,out] p_len Buffer size as input, length of prepared data as output.
+ *
+ * @return True if message fits into the buffer, false otherwise
+ */
+static bool msg_to_buf(nrf_log_entry_t * p_msg, uint8_t * p_buf, size_t * p_len)
+{
+ uint32_t data_len;
+ nrf_log_header_t header = {0};
+ uint32_t memobj_offset = HEADER_SIZE*sizeof(uint32_t);
+
+ nrf_memobj_read(p_msg, &header, HEADER_SIZE*sizeof(uint32_t), 0);
+
+ memcpy(p_buf, &header, sizeof(nrf_log_header_t));
+ p_buf += sizeof(nrf_log_header_t);
+
+ switch (header.base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ {
+ data_len = header.base.std.nargs * sizeof(uint32_t);
+ break;
+ }
+ case HEADER_TYPE_HEXDUMP:
+ {
+ data_len = saturate_align_length(header.base.hexdump.len);
+ break;
+ }
+ default:
+ *p_len = 0;
+ return false;
+ }
+ nrf_memobj_read(p_msg, p_buf, data_len, memobj_offset);
+
+ if (*p_len >= sizeof(nrf_log_header_t) + data_len)
+ {
+ *p_len = sizeof(nrf_log_header_t) + data_len;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/**
+ * @brief Function for getting logger message stored in flash.
+ *
+ * @param[in] p_buf Pointer to the location where message is stored.
+ * @param[out] pp_header Pointer to the log message header.
+ * @param[out] pp_data Pointer to the log message data (arguments or data in case of hexdump).
+ *
+ * @return True if message was successfully fetched, false otherwise.
+ */
+static bool msg_from_buf(uint32_t * p_buf,
+ nrf_log_header_t * * pp_header,
+ uint8_t * * pp_data,
+ uint32_t * p_len)
+{
+ *pp_header = (nrf_log_header_t *)p_buf;
+ *pp_data = (uint8_t *)&p_buf[LOG_HEADER_LEN_WORDS];
+
+ uint32_t data_len;
+
+ switch ((*pp_header)->base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ {
+ data_len = ((*pp_header)->base.std.nargs)*sizeof(uint32_t);
+ break;
+ }
+ case HEADER_TYPE_HEXDUMP:
+ {
+
+ data_len = saturate_align_length((*pp_header)->base.hexdump.len);
+ break;
+ }
+ default:
+ return false;
+ }
+
+ *p_len = LOG_HEADER_LEN + data_len;
+ return true;
+}
+
+/**
+ * @brief Function for processing log message queue.
+ *
+ * If writing to flash is synchronous then function drains the queue and writes all messages to flash.
+ * If writing to flash is asynchronous then function starts single write operation. In asynchronous mode
+ * function is called when new message is put into the queue from from flash operation callback.
+ *
+ * Function detects the situation that flash module reports attempt to write outside dedicated area.
+ * In that case flash backend stops writing any new messages.
+ *
+ * @param p_queue Queue will log messages
+ * @param fstorage_blocking If true it indicates that flash operations are blocking, event handler is not used.
+ */
+static void log_msg_queue_process(nrf_queue_t const * p_queue, bool fstorage_blocking)
+{
+ nrf_log_entry_t * p_msg;
+ bool busy = false;
+ while (nrf_queue_pop(p_queue, &p_msg) == NRF_SUCCESS)
+ {
+ ret_code_t err_code;
+
+ m_curr_len = sizeof(m_flash_buf);
+ if (!msg_to_buf(p_msg, (uint8_t *)m_flash_buf, &m_curr_len))
+ {
+ continue;
+ }
+
+ err_code = nrf_fstorage_write(&m_log_flash_fstorage, m_curr_addr, m_flash_buf, m_curr_len, p_msg);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (fstorage_blocking)
+ {
+ m_curr_addr += m_curr_len;
+
+ nrf_memobj_put(p_msg);
+ }
+ else
+ {
+ busy = true;
+ break;
+ }
+ }
+ else if (!fstorage_blocking && (err_code == NRF_ERROR_NO_MEM))
+ {
+ // fstorage queue got full. Drop entry.
+ nrf_memobj_put(p_msg);
+ m_dropped++;
+ break;
+ }
+ else if (err_code == NRF_ERROR_INVALID_ADDR)
+ {
+ // Trying to write outside the area, flash log is full. Skip any new writes.
+ nrf_memobj_put(p_msg);
+ m_state = LOG_BACKEND_FLASH_INACTIVE;
+ }
+ else
+ {
+ ASSERT(false);
+ }
+ }
+
+ if (!busy)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&m_busy_flag));
+ }
+}
+
+static void queue_element_drop(nrf_queue_t const * p_queue)
+{
+ nrf_log_entry_t * p_msg;
+ if (nrf_queue_pop(p_queue, &p_msg) == NRF_SUCCESS)
+ {
+ m_dropped++;
+ nrf_memobj_put(p_msg);
+ }
+}
+
+static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
+{
+ if (m_state == LOG_BACKEND_FLASH_ACTIVE)
+ {
+ switch (p_evt->id)
+ {
+ case NRF_FSTORAGE_EVT_WRITE_RESULT:
+ {
+ if (p_evt->result == NRF_SUCCESS)
+ {
+ m_curr_addr += m_curr_len;
+ m_curr_len = 0;
+ log_msg_queue_process(mp_flashlog_queue, false);
+ }
+ else
+ {
+ m_dropped++;
+ }
+
+ if (p_evt->p_param)
+ {
+ nrf_memobj_put((nrf_log_entry_t *)p_evt->p_param);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if ((m_state == LOG_BACKEND_FLASH_INACTIVE) &&
+ (p_evt->id == NRF_FSTORAGE_EVT_ERASE_RESULT) &&
+ (p_evt->addr == RUNTIME_START_ADDR))
+ {
+ m_state = LOG_BACKEND_FLASH_ACTIVE;
+ }
+}
+
+/**
+ * @brief Function for enqueueing new message.
+ *
+ * If queue is full then the oldest message is freed.
+ *
+ * @param p_queue Queue.
+ * @param p_msg Message.
+ *
+ * @return Number of dropped messages
+ */
+static uint32_t message_enqueue(nrf_queue_t const * p_queue, nrf_log_entry_t * p_msg)
+{
+ uint32_t dropped = 0;
+
+ //flag was set, busy so enqueue message
+ while (nrf_queue_push(p_queue, &p_msg) != NRF_SUCCESS)
+ {
+
+ nrf_log_entry_t * p_old_msg;
+ if (nrf_queue_pop(p_queue, &p_old_msg) == NRF_SUCCESS)
+ {
+ nrf_memobj_put(p_old_msg);
+ dropped++;
+ }
+ }
+
+ return dropped;
+}
+
+
+void nrf_log_backend_flashlog_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ if (m_state == LOG_BACKEND_FLASH_ACTIVE)
+ {
+ nrf_memobj_get(p_msg);
+
+ m_dropped += message_enqueue(mp_flashlog_queue, p_msg);
+
+ if (nrf_atomic_flag_set_fetch(&m_busy_flag) == 0)
+ {
+ log_msg_queue_process(mp_flashlog_queue, false);
+ }
+ }
+}
+
+
+void nrf_log_backend_crashlog_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ if (m_state != LOG_BACKEND_FLASH_INACTIVE)
+ {
+ nrf_memobj_get(p_msg);
+
+ UNUSED_RETURN_VALUE(message_enqueue(mp_crashlog_queue, p_msg));
+ }
+
+ if (m_state == LOG_BACKEND_FLASH_IN_PANIC)
+ {
+ log_msg_queue_process(mp_crashlog_queue, true);
+ }
+}
+
+void nrf_log_backend_flashlog_flush(nrf_log_backend_t const * p_backend)
+{
+ queue_element_drop(mp_flashlog_queue);
+}
+
+void nrf_log_backend_crashlog_flush(nrf_log_backend_t const * p_backend)
+{
+ queue_element_drop(mp_crashlog_queue);
+}
+
+void nrf_log_backend_flashlog_panic_set(nrf_log_backend_t const * p_backend)
+{
+ /* Empty */
+}
+
+/**
+ * @brief Function for injecting log message which will indicate start of crash log.
+ */
+static void crashlog_marker_inject(void)
+{
+ nrf_log_header_t crashlog_marker_hdr = {
+ .base = {
+ .std = {
+ .type = HEADER_TYPE_STD,
+ .severity = NRF_LOG_SEVERITY_INFO_RAW,
+ .nargs = 0,
+ .addr = (uint32_t)crashlog_str & STD_ADDR_MASK
+ }
+ },
+ .module_id = 0,
+ .timestamp = 0,
+ };
+ m_flash_buf[0] = crashlog_marker_hdr.base.raw;
+ m_flash_buf[1] = crashlog_marker_hdr.module_id;
+ m_flash_buf[2] = crashlog_marker_hdr.timestamp;
+ (void)nrf_fstorage_write(&m_log_flash_fstorage, m_curr_addr, m_flash_buf, LOG_HEADER_LEN, NULL);
+ m_curr_addr += LOG_HEADER_LEN;
+}
+
+
+void nrf_log_backend_crashlog_panic_set(nrf_log_backend_t const * p_backend)
+{
+ if (nrf_fstorage_init(&m_log_flash_fstorage, &nrf_fstorage_nvmc, NULL) == NRF_SUCCESS)
+ {
+ m_state = LOG_BACKEND_FLASH_IN_PANIC;
+
+ /* In case of Softdevice MWU may protect access to NVMC. */
+ NVIC_DisableIRQ(MWU_IRQn);
+
+ log_msg_queue_process(mp_flashlog_queue, true);
+
+ crashlog_marker_inject();
+
+ log_msg_queue_process(mp_crashlog_queue, true);
+ }
+ else
+ {
+ m_state = LOG_BACKEND_FLASH_INACTIVE;
+ }
+}
+
+/**
+ * @brief Function for determining first empty location in area dedicated for flash logger backend.
+ */
+static uint32_t empty_addr_get(void)
+{
+ uint32_t token = 0;
+ nrf_log_header_t * p_dummy_header;
+ uint8_t * p_dummy_data;
+
+ while(nrf_log_backend_flash_next_entry_get(&token, &p_dummy_header, &p_dummy_data) == NRF_SUCCESS)
+ {
+
+ }
+
+ return token;
+}
+
+
+ret_code_t nrf_log_backend_flash_init(nrf_fstorage_api_t const * p_fs_api)
+{
+ ret_code_t err_code;
+
+
+ uint32_t start_addr = RUNTIME_START_ADDR;
+ uint32_t end_addr = start_addr + FLASH_LOG_SIZE - 1;
+
+ m_log_flash_fstorage.start_addr = start_addr;
+ m_log_flash_fstorage.end_addr = end_addr;
+
+ err_code = nrf_fstorage_init(&m_log_flash_fstorage, p_fs_api, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ m_curr_addr = empty_addr_get();
+ m_state = LOG_BACKEND_FLASH_ACTIVE;
+
+ return err_code;
+}
+
+
+ret_code_t nrf_log_backend_flash_next_entry_get(uint32_t * p_token,
+ nrf_log_header_t * * pp_header,
+ uint8_t * * pp_data)
+{
+ uint32_t * p_addr = p_token;
+ uint32_t len;
+
+ *p_addr = (*p_addr == 0) ? RUNTIME_START_ADDR : *p_addr;
+
+ if (nrf_fstorage_rmap(&m_log_flash_fstorage, *p_addr) == NULL)
+ {
+ //Supports only memories which can be mapped for reading.
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (msg_from_buf((uint32_t *)*p_addr, pp_header, pp_data, &len))
+ {
+ *p_addr += len;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+}
+
+
+ret_code_t nrf_log_backend_flash_erase(void)
+{
+ ret_code_t err_code;
+
+ m_state = LOG_BACKEND_FLASH_INACTIVE;
+ err_code = nrf_fstorage_erase(&m_log_flash_fstorage, RUNTIME_START_ADDR, NRF_LOG_BACKEND_PAGES, NULL);
+
+ m_curr_addr = RUNTIME_START_ADDR;
+
+ return err_code;
+}
+
+#if NRF_LOG_BACKEND_FLASHLOG_ENABLED
+const nrf_log_backend_api_t nrf_log_backend_flashlog_api = {
+ .put = nrf_log_backend_flashlog_put,
+ .flush = nrf_log_backend_flashlog_flush,
+ .panic_set = nrf_log_backend_flashlog_panic_set,
+};
+#endif
+
+#if NRF_LOG_BACKEND_CRASHLOG_ENABLED
+const nrf_log_backend_api_t nrf_log_backend_crashlog_api = {
+ .put = nrf_log_backend_crashlog_put,
+ .flush = nrf_log_backend_crashlog_flush,
+ .panic_set = nrf_log_backend_crashlog_panic_set,
+};
+#endif
+
+#if NRF_LOG_BACKEND_FLASH_CLI_CMDS
+#include "nrf_cli.h"
+
+static uint8_t m_buffer[64];
+static nrf_cli_t const * mp_cli;
+
+static void cli_tx(void const * p_context, char const * p_buffer, size_t len);
+
+static nrf_fprintf_ctx_t m_fprintf_ctx =
+{
+ .p_io_buffer = (char *)m_buffer,
+ .io_buffer_size = sizeof(m_buffer)-1,
+ .io_buffer_cnt = 0,
+ .auto_flush = true,
+ .p_user_ctx = &mp_cli,
+ .fwrite = cli_tx
+};
+
+
+static void flashlog_clear_cmd(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ }
+
+ UNUSED_RETURN_VALUE(nrf_log_backend_flash_erase());
+}
+
+#include "nrf_delay.h"
+static void cli_tx(void const * p_context, char const * p_buffer, size_t len)
+{
+ nrf_cli_t * * pp_cli = (nrf_cli_t * *)p_context;
+ char * p_strbuf = (char *)&p_buffer[len];
+ *p_strbuf = '\0';
+ nrf_cli_fprintf((nrf_cli_t const *)*pp_cli, NRF_CLI_DEFAULT, p_buffer);
+ // nrf_delay_ms(10);
+}
+
+
+static void entry_process(nrf_cli_t const * p_cli, nrf_log_header_t * p_header, uint8_t * p_data)
+{
+ mp_cli = p_cli;
+
+ nrf_log_str_formatter_entry_params_t params =
+ {
+ .timestamp = p_header->timestamp,
+ .module_id = p_header->module_id,
+ .use_colors = 0,
+ };
+
+ switch (p_header->base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ {
+ params.severity = (nrf_log_severity_t)p_header->base.std.severity;
+ nrf_log_std_entry_process((const char *)((uint32_t)p_header->base.std.addr),
+ (uint32_t *)p_data,
+ p_header->base.std.nargs,
+ &params,
+ &m_fprintf_ctx);
+ break;
+ }
+ case HEADER_TYPE_HEXDUMP:
+ {
+ params.severity = (nrf_log_severity_t)p_header->base.hexdump.severity;
+
+ nrf_log_hexdump_entry_process(p_data,
+ p_header->base.hexdump.len,
+ &params,
+ &m_fprintf_ctx);
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+
+}
+
+
+static void flashlog_read_cmd(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ }
+
+ uint32_t token = 0;
+ uint8_t * p_data = NULL;
+ bool empty = true;
+ nrf_log_header_t * p_header;
+
+ while (1)
+ {
+ if (nrf_log_backend_flash_next_entry_get(&token, &p_header, &p_data) == NRF_SUCCESS)
+ {
+ entry_process(p_cli, p_header, p_data);
+ empty = false;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (empty)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Flash log empty\r\n");
+ }
+}
+
+
+static void flashlog_status_cmd(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Flash log status:\r\n");
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t\t- Location (address: 0x%08X, length: %d)\r\n",
+ RUNTIME_START_ADDR, FLASH_LOG_SIZE);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t\t- Current usage:%d%% (%d of %d bytes used)\r\n",
+ 100ul * (m_curr_addr - RUNTIME_START_ADDR)/FLASH_LOG_SIZE,
+ m_curr_addr - RUNTIME_START_ADDR,
+ FLASH_LOG_SIZE);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t\t- Dropped logs: %d\r\n", m_dropped);
+
+
+}
+
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_flashlog_cmd)
+{
+ NRF_CLI_CMD(clear, NULL, "Remove logs", flashlog_clear_cmd),
+ NRF_CLI_CMD(read, NULL, "Read stored logs", flashlog_read_cmd),
+ NRF_CLI_CMD(status, NULL, "Flash log status", flashlog_status_cmd),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(flashlog, &m_flashlog_cmd, "Commands for reading logs stored in non-volatile memory", NULL);
+
+#endif //NRF_LOG_BACKEND_FLASH_CLI_CMDS
+
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_FLASH)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c
new file mode 100644
index 0000000..1ff3a26
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+#include "nrf_log_backend_rtt.h"
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#include "nrf_delay.h"
+#include <SEGGER_RTT_Conf.h>
+#include <SEGGER_RTT.h>
+
+static bool m_host_present;
+
+static uint8_t m_string_buff[NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE];
+
+void nrf_log_backend_rtt_init(void)
+{
+ SEGGER_RTT_Init();
+}
+
+static void serial_tx(void const * p_context, char const * buffer, size_t len)
+{
+ if (len)
+ {
+ uint32_t idx = 0;
+ uint32_t processed;
+ uint32_t watchdog_counter = NRF_LOG_BACKEND_RTT_TX_RETRY_CNT;
+ do
+ {
+ processed = SEGGER_RTT_WriteNoLock(0, &buffer[idx], len);
+ idx += processed;
+ len -= processed;
+ if (processed == 0)
+ {
+ /* There are two possible reasons for not writing any data to RTT:
+ * - The host is not connected and not reading the data.
+ * - The buffer got full and will be read by the host.
+ * These two situations are distinguished using the following algorithm.
+ * At the begining, the module assumes that the host is active,
+ * so when no data is read, it busy waits and retries.
+ * If, after retrying, the host reads the data, the module assumes that the host is active.
+ * If it fails, the module assumes that the host is inactive and stores that information. On next
+ * call, only one attempt takes place. The host is marked as active if the attempt is successful.
+ */
+ if (!m_host_present)
+ {
+ break;
+ }
+ else
+ {
+ nrf_delay_ms(NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS);
+ watchdog_counter--;
+ if (watchdog_counter == 0)
+ {
+ m_host_present = false;
+ break;
+ }
+ }
+ }
+ m_host_present = true;
+ } while (len);
+ }
+}
+static void nrf_log_backend_rtt_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff, NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE, serial_tx);
+}
+
+static void nrf_log_backend_rtt_flush(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+static void nrf_log_backend_rtt_panic_set(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+const nrf_log_backend_api_t nrf_log_backend_rtt_api = {
+ .put = nrf_log_backend_rtt_put,
+ .flush = nrf_log_backend_rtt_flush,
+ .panic_set = nrf_log_backend_rtt_panic_set,
+};
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c
new file mode 100644
index 0000000..7db0074
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+
+void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg,
+ uint8_t * p_buffer,
+ uint32_t length,
+ nrf_fprintf_fwrite tx_func)
+{
+ nrf_memobj_get(p_msg);
+
+ nrf_fprintf_ctx_t fprintf_ctx = {
+ .p_io_buffer = (char *)p_buffer,
+ .io_buffer_size = length,
+ .io_buffer_cnt = 0,
+ .auto_flush = false,
+ .p_user_ctx = NULL,
+ .fwrite = tx_func
+ };
+
+ nrf_log_str_formatter_entry_params_t params;
+
+ nrf_log_header_t header;
+ uint32_t memobj_offset = 0;
+ nrf_memobj_read(p_msg, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset = HEADER_SIZE*sizeof(uint32_t);
+
+ params.timestamp = header.timestamp;
+ params.module_id = header.module_id;
+ params.dropped = header.dropped;
+ params.use_colors = NRF_LOG_USES_COLORS;
+
+ /*lint -save -e438*/
+ if (header.base.generic.type == HEADER_TYPE_STD)
+ {
+ char const * p_log_str = (char const *)((uint32_t)header.base.std.addr);
+ params.severity = (nrf_log_severity_t)header.base.std.severity;
+ uint32_t nargs = header.base.std.nargs;
+ uint32_t args[NRF_LOG_MAX_NUM_OF_ARGS];
+
+ nrf_memobj_read(p_msg, args, nargs*sizeof(uint32_t), memobj_offset);
+ memobj_offset += (nargs*sizeof(uint32_t));
+
+ nrf_log_std_entry_process(p_log_str,
+ args,
+ nargs,
+ &params,
+ &fprintf_ctx);
+
+ }
+ else if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t data_len = header.base.hexdump.len;
+ params.severity = (nrf_log_severity_t)header.base.hexdump.severity;
+ uint8_t data_buf[8];
+ uint32_t chunk_len;
+ do
+ {
+ chunk_len = sizeof(data_buf) > data_len ? data_len : sizeof(data_buf);
+ nrf_memobj_read(p_msg, data_buf, chunk_len, memobj_offset);
+ memobj_offset += chunk_len;
+ data_len -= chunk_len;
+
+ nrf_log_hexdump_entry_process(data_buf,
+ chunk_len,
+ &params,
+ &fprintf_ctx);
+ } while (data_len > 0);
+ }
+ nrf_memobj_put(p_msg);
+ /*lint -restore*/
+}
+#endif //NRF_LOG_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h
new file mode 100644
index 0000000..22d26f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_BACKEND_SERIAL_H
+#define NRF_LOG_BACKEND_SERIAL_H
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_backend_serial Common part of serial backends
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log serial backend common put function.
+ */
+
+
+#include "nrf_log_backend_interface.h"
+#include "nrf_fprintf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief A function for processing logger entry with simple serial interface as output.
+ *
+ *
+ */
+void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg,
+ uint8_t * p_buffer,
+ uint32_t length,
+ nrf_fprintf_fwrite tx_func);
+
+#endif //NRF_LOG_BACKEND_SERIAL_H
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c
new file mode 100644
index 0000000..76dad8a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
+#include "nrf_log_backend_uart.h"
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_internal.h"
+#include "nrf_drv_uart.h"
+#include "app_error.h"
+
+nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+
+static uint8_t m_string_buff[NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE];
+static volatile bool m_xfer_done;
+static bool m_async_mode;
+static void uart_evt_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ m_xfer_done = true;
+}
+
+static void uart_init(bool async_mode)
+{
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.pseltxd = NRF_LOG_BACKEND_UART_TX_PIN;
+ config.pselrxd = NRF_UART_PSEL_DISCONNECTED;
+ config.pselcts = NRF_UART_PSEL_DISCONNECTED;
+ config.pselrts = NRF_UART_PSEL_DISCONNECTED;
+ config.baudrate = (nrf_uart_baudrate_t)NRF_LOG_BACKEND_UART_BAUDRATE;
+ ret_code_t err_code = nrf_drv_uart_init(&m_uart, &config, async_mode ? uart_evt_handler : NULL);
+ APP_ERROR_CHECK(err_code);
+
+ m_async_mode = async_mode;
+}
+
+void nrf_log_backend_uart_init(void)
+{
+ bool async_mode = NRF_LOG_DEFERRED ? true : false;
+ uart_init(async_mode);
+}
+
+static void serial_tx(void const * p_context, char const * p_buffer, size_t len)
+{
+ uint8_t len8 = (uint8_t)(len & 0x000000FF);
+ m_xfer_done = false;
+ ret_code_t err_code = nrf_drv_uart_tx(&m_uart, (uint8_t *)p_buffer, len8);
+ APP_ERROR_CHECK(err_code);
+ /* wait for completion since buffer is reused*/
+ while (m_async_mode && (m_xfer_done == false))
+ {
+
+ }
+
+}
+
+static void nrf_log_backend_uart_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff,
+ NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE, serial_tx);
+}
+
+static void nrf_log_backend_uart_flush(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+static void nrf_log_backend_uart_panic_set(nrf_log_backend_t const * p_backend)
+{
+ nrf_drv_uart_uninit(&m_uart);
+
+ uart_init(false);
+}
+
+const nrf_log_backend_api_t nrf_log_backend_uart_api = {
+ .put = nrf_log_backend_uart_put,
+ .flush = nrf_log_backend_uart_flush,
+ .panic_set = nrf_log_backend_uart_panic_set,
+};
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h
new file mode 100644
index 0000000..ba8a574
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_CTRL_INTERNAL_H
+#define NRF_LOG_CTRL_INTERNAL_H
+/**
+ * @cond (NODOX)
+ * @defgroup nrf_log_ctrl_internal Auxiliary internal types declarations
+ * @{
+ * @internal
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_INTERNAL_INIT(...) \
+ nrf_log_init(GET_VA_ARG_1(__VA_ARGS__), \
+ GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__, NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY)))
+
+#define NRF_LOG_INTERNAL_PROCESS() nrf_log_frontend_dequeue()
+#define NRF_LOG_INTERNAL_FLUSH() \
+ do { \
+ while (NRF_LOG_INTERNAL_PROCESS()); \
+ } while (0)
+
+#define NRF_LOG_INTERNAL_FINAL_FLUSH() \
+ do { \
+ nrf_log_panic(); \
+ NRF_LOG_INTERNAL_FLUSH(); \
+ } while (0)
+
+
+#else // NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_INTERNAL_PROCESS() false
+#define NRF_LOG_INTERNAL_FLUSH()
+#define NRF_LOG_INTERNAL_INIT(timestamp_func) NRF_SUCCESS
+#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \
+ UNUSED_PARAMETER(default_handler); UNUSED_PARAMETER(bytes_handler)
+#define NRF_LOG_INTERNAL_FINAL_FLUSH()
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
+
+/** @}
+ * @endcond
+ */
+#endif // NRF_LOG_CTRL_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c
new file mode 100644
index 0000000..c844f2e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_default_backends.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_internal.h"
+#include "nrf_assert.h"
+
+#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
+#include "nrf_log_backend_rtt.h"
+NRF_LOG_BACKEND_RTT_DEF(rtt_log_backend);
+#endif
+
+#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
+#include "nrf_log_backend_uart.h"
+NRF_LOG_BACKEND_UART_DEF(uart_log_backend);
+#endif
+
+void nrf_log_default_backends_init(void)
+{
+ int32_t backend_id = -1;
+ (void)backend_id;
+#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
+ nrf_log_backend_rtt_init();
+ backend_id = nrf_log_backend_add(&rtt_log_backend.backend, NRF_LOG_SEVERITY_DEBUG);
+ ASSERT(backend_id >= 0);
+ nrf_log_backend_enable(&rtt_log_backend.backend);
+#endif
+
+#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
+ nrf_log_backend_uart_init();
+ backend_id = nrf_log_backend_add(&uart_log_backend.backend, NRF_LOG_SEVERITY_DEBUG);
+ ASSERT(backend_id >= 0);
+ nrf_log_backend_enable(&uart_log_backend.backend);
+#endif
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c
new file mode 100644
index 0000000..4e65702
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c
@@ -0,0 +1,1245 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "nrf_log.h"
+#include "nrf_log_internal.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_section.h"
+#include "nrf_memobj.h"
+#include "nrf_atomic.h"
+#include <string.h>
+
+STATIC_ASSERT((NRF_LOG_BUFSIZE % 4) == 0);
+STATIC_ASSERT(IS_POWER_OF_TWO(NRF_LOG_BUFSIZE));
+
+#define NRF_LOG_BUF_WORDS (NRF_LOG_BUFSIZE/4)
+
+#if NRF_LOG_BUF_WORDS < 32
+#warning "NRF_LOG_BUFSIZE too small, significant number of logs may be lost."
+#endif
+
+NRF_MEMOBJ_POOL_DEF(log_mempool, NRF_LOG_MSGPOOL_ELEMENT_SIZE, NRF_LOG_MSGPOOL_ELEMENT_COUNT);
+
+#define NRF_LOG_BACKENDS_FULL 0xFF
+#define NRF_LOG_FILTER_BITS_PER_BACKEND 3
+#define NRF_LOG_MAX_BACKENDS (32/NRF_LOG_FILTER_BITS_PER_BACKEND)
+#define NRF_LOG_MAX_HEXDUMP (NRF_LOG_MSGPOOL_ELEMENT_SIZE*NRF_LOG_MSGPOOL_ELEMENT_COUNT/2)
+
+/**
+ * brief An internal control block of the logger
+ *
+ * @note Circular buffer is using never cleared indexes and a mask. It means
+ * that logger may break when indexes overflows. However, it is quite unlikely.
+ * With rate of 1000 log entries with 2 parameters per second such situation
+ * would happen after 12 days.
+ */
+typedef struct
+{
+ uint32_t wr_idx; // Current write index (never reset)
+ uint32_t rd_idx; // Current read index (never_reset)
+ uint32_t mask; // Size of buffer (must be power of 2) presented as mask
+ uint32_t buffer[NRF_LOG_BUF_WORDS];
+ nrf_log_timestamp_func_t timestamp_func; // A pointer to function that returns timestamp
+ nrf_log_backend_t * p_backend_head;
+ nrf_atomic_flag_t log_skipping;
+ nrf_atomic_flag_t log_skipped;
+ nrf_atomic_u32_t log_dropped_cnt;
+ bool autoflush;
+} log_data_t;
+
+static log_data_t m_log_data;
+
+/*lint -save -esym(526,log_const_data*) -esym(526,log_dynamic_data*)*/
+NRF_SECTION_DEF(log_dynamic_data, NRF_LOG_DYNAMIC_STRUCT_NAME);
+NRF_SECTION_DEF(log_const_data, nrf_log_module_const_data_t);
+/*lint -restore*/
+NRF_LOG_MODULE_REGISTER();
+// Helper macros for section variables.
+#define NRF_LOG_DYNAMIC_SECTION_VARS_GET(i) NRF_SECTION_ITEM_GET(log_dynamic_data, NRF_LOG_DYNAMIC_STRUCT_NAME, (i))
+
+#define NRF_LOG_CONST_SECTION_VARS_GET(i) NRF_SECTION_ITEM_GET(log_const_data, nrf_log_module_const_data_t, (i))
+#define NRF_LOG_CONST_SECTION_VARS_COUNT NRF_SECTION_ITEM_COUNT(log_const_data, nrf_log_module_const_data_t)
+
+#define PUSHED_HEADER_FILL(P_HDR, OFFSET, LENGTH) \
+ (P_HDR)->base.raw = 0; \
+ (P_HDR)->base.pushed.type = HEADER_TYPE_PUSHED; \
+ (P_HDR)->base.pushed.offset = OFFSET; \
+ (P_HDR)->base.pushed.len = LENGTH
+
+
+ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq)
+{
+ if (NRF_LOG_USES_TIMESTAMP && (timestamp_func == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_log_data.mask = NRF_LOG_BUF_WORDS - 1;
+ m_log_data.wr_idx = 0;
+ m_log_data.rd_idx = 0;
+ m_log_data.log_skipped = 0;
+ m_log_data.log_skipping = 0;
+ m_log_data.autoflush = NRF_LOG_DEFERRED ? false : true;
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ nrf_log_str_formatter_timestamp_freq_set(timestamp_freq);
+ m_log_data.timestamp_func = timestamp_func;
+ }
+
+ ret_code_t err_code = nrf_memobj_pool_init(&log_mempool);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint32_t modules_cnt = NRF_LOG_CONST_SECTION_VARS_COUNT;
+ uint32_t i;
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint32_t j;
+ //sort modules by name
+ for (i = 0; i < modules_cnt; i++)
+ {
+ uint32_t idx = 0;
+
+ for (j = 0; j < modules_cnt; j++)
+ {
+ if (i != j)
+ {
+ char const * p_name0 = NRF_LOG_CONST_SECTION_VARS_GET(i)->p_module_name;
+ char const * p_name1 = NRF_LOG_CONST_SECTION_VARS_GET(j)->p_module_name;
+ if (strncmp(p_name0, p_name1, 20) > 0)
+ {
+ idx++;
+ }
+ }
+
+ }
+ nrf_log_module_dynamic_data_t * p_module_ddata =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ p_module_ddata->filter = 0;
+ p_module_ddata->module_id = i;
+ p_module_ddata->order_idx = idx;
+ }
+ }
+ else
+ {
+ for(i = 0; i < modules_cnt; i++)
+ {
+ nrf_log_module_reduced_dynamic_data_t * p_module_ddata =
+ (nrf_log_module_reduced_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ p_module_ddata->module_id = i;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t nrf_log_module_cnt_get(void)
+{
+ return NRF_LOG_CONST_SECTION_VARS_COUNT;
+}
+
+static ret_code_t module_idx_get(uint32_t * p_idx, bool ordered_idx)
+{
+ if (ordered_idx)
+ {
+ uint32_t module_cnt = nrf_log_module_cnt_get();
+ uint32_t i;
+ for (i = 0; i < module_cnt; i++)
+ {
+ nrf_log_module_dynamic_data_t * p_module_data =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ if (p_module_data->order_idx == *p_idx)
+ {
+ *p_idx = i;
+ return NRF_SUCCESS;
+ }
+ }
+ return NRF_ERROR_NOT_FOUND;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+const char * nrf_log_module_name_get(uint32_t module_id, bool ordered_idx)
+{
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_const_data_t * p_module_data = NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ return p_module_data->p_module_name;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity)
+{
+ nrf_log_module_const_data_t * p_module_data = NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ uint8_t color_id;
+ switch (severity)
+ {
+ case NRF_LOG_SEVERITY_ERROR:
+ color_id = NRF_LOG_ERROR_COLOR;
+ break;
+ case NRF_LOG_SEVERITY_WARNING:
+ color_id = NRF_LOG_WARNING_COLOR;
+ break;
+ case NRF_LOG_SEVERITY_INFO:
+ color_id = p_module_data->info_color_id;
+ break;
+ case NRF_LOG_SEVERITY_DEBUG:
+ color_id = p_module_data->debug_color_id;
+ break;
+ default:
+ color_id = 0;
+ break;
+ }
+ return color_id;
+}
+
+static uint32_t higher_lvl_get(uint32_t lvls)
+{
+ uint32_t top_lvl = 0;
+ uint32_t tmp_lvl;
+ uint32_t i;
+
+ //Find highest level enabled by backends
+ for (i = 0; i < (32/NRF_LOG_LEVEL_BITS); i+=NRF_LOG_LEVEL_BITS)
+ {
+ tmp_lvl = BF_GET(lvls,NRF_LOG_LEVEL_BITS, i);
+ if (tmp_lvl > top_lvl)
+ {
+ top_lvl = tmp_lvl;
+ }
+ }
+ return top_lvl;
+}
+
+void nrf_log_module_filter_set(uint32_t backend_id, uint32_t module_id, nrf_log_severity_t severity)
+{
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(module_id);
+ p_module_filter->filter_lvls &= ~(NRF_LOG_LEVEL_MASK << (NRF_LOG_LEVEL_BITS * backend_id));
+ p_module_filter->filter_lvls |= (severity & NRF_LOG_LEVEL_MASK) << (NRF_LOG_LEVEL_BITS * backend_id);
+ p_module_filter->filter = higher_lvl_get(p_module_filter->filter_lvls);
+ }
+}
+
+static nrf_log_severity_t nrf_log_module_init_filter_get(uint32_t module_id)
+{
+ nrf_log_module_const_data_t * p_module_data =
+ NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ return NRF_LOG_FILTERS_ENABLED ? p_module_data->initial_lvl : p_module_data->compiled_lvl;
+}
+
+nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
+ uint32_t module_id,
+ bool ordered_idx,
+ bool dynamic)
+{
+ nrf_log_severity_t severity = NRF_LOG_SEVERITY_NONE;
+ if (NRF_LOG_FILTERS_ENABLED && dynamic)
+ {
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(module_id);
+ severity = (nrf_log_severity_t)((p_module_filter->filter_lvls >> (NRF_LOG_LEVEL_BITS * backend_id)) &
+ NRF_LOG_LEVEL_MASK);
+ }
+ }
+ else if (!dynamic)
+ {
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_const_data_t * p_module_data =
+ NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ severity = (nrf_log_severity_t)p_module_data->compiled_lvl;
+ }
+ }
+ return severity;
+}
+/**
+ * Function examines current header and omits pushed strings and packets which are in progress.
+ */
+static bool invalid_packets_pushed_str_omit(nrf_log_header_t const * p_header, uint32_t * p_rd_idx)
+{
+ bool ret = false;
+ if ((p_header->base.generic.type == HEADER_TYPE_PUSHED) || (p_header->base.generic.in_progress == 1))
+ {
+ if (p_header->base.generic.in_progress == 1)
+ {
+ switch (p_header->base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ *p_rd_idx += (HEADER_SIZE + p_header->base.std.nargs);
+ break;
+ case HEADER_TYPE_HEXDUMP:
+ *p_rd_idx += (HEADER_SIZE + p_header->base.hexdump.len);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+ else
+ {
+ *p_rd_idx +=
+ (PUSHED_HEADER_SIZE + p_header->base.pushed.len + p_header->base.pushed.offset);
+ }
+ ret = true;
+ }
+ return ret;
+}
+/**
+ * @brief Skips the oldest, not pushed logs to make space for new logs.
+ * @details This function moves forward read index to prepare space for new logs.
+ */
+
+static uint32_t log_skip(void)
+{
+ uint16_t dropped = 0;
+
+ (void)nrf_atomic_flag_set(&m_log_data.log_skipped);
+ (void)nrf_atomic_flag_set(&m_log_data.log_skipping);
+
+ uint32_t rd_idx = m_log_data.rd_idx;
+ uint32_t mask = m_log_data.mask;
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_log_header_t header;
+
+ // Skip any string that is pushed to the circular buffer.
+ do {
+ if (invalid_packets_pushed_str_omit(p_header, &rd_idx))
+ {
+ //something was omitted. Point to new header and try again.
+ p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+
+ uint32_t i;
+ for (i = 0; i < HEADER_SIZE; i++)
+ {
+ ((uint32_t*)&header)[i] = m_log_data.buffer[rd_idx++ & mask];
+ }
+
+ switch (header.base.generic.type)
+ {
+ case HEADER_TYPE_HEXDUMP:
+ dropped = header.dropped;
+ rd_idx += CEIL_DIV(header.base.hexdump.len, sizeof(uint32_t));
+ break;
+ case HEADER_TYPE_STD:
+ dropped = header.dropped;
+ rd_idx += header.base.std.nargs;
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+
+ uint32_t log_skipping_tmp = nrf_atomic_flag_clear_fetch(&m_log_data.log_skipping);
+ //update read index only if log_skip was not interrupted by another log skip
+ if (log_skipping_tmp)
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+
+ return (uint32_t)dropped;
+}
+
+/**
+ * @brief Function for getting number of dropped logs. Dropped counter is reset after reading.
+ *
+ * @return Number of dropped logs saturated to 16 bits.
+ */
+static inline uint32_t dropped_sat16_get(void)
+{
+ uint32_t dropped = nrf_atomic_u32_fetch_store(&m_log_data.log_dropped_cnt, 0);
+ return __USAT(dropped, 16); //Saturate to 16 bits
+}
+
+
+static inline void std_header_set(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t nargs,
+ uint32_t wr_idx,
+ uint32_t mask)
+{
+
+
+ //Prepare header - in reverse order to ensure that packet type is validated (set to STD as last action)
+ uint32_t module_id = severity_mid >> NRF_LOG_MODULE_ID_POS;
+ uint32_t dropped = dropped_sat16_get();
+ ASSERT(module_id < nrf_log_module_cnt_get());
+ m_log_data.buffer[(wr_idx + 1) & mask] = module_id | (dropped << 16);
+
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.buffer[(wr_idx + 2) & mask] = m_log_data.timestamp_func();
+ }
+
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
+ p_header->base.std.severity = severity_mid & NRF_LOG_LEVEL_MASK;
+ p_header->base.std.nargs = nargs;
+ p_header->base.std.addr = ((uint32_t)(p_str) & STD_ADDR_MASK);
+ p_header->base.std.type = HEADER_TYPE_STD;
+ p_header->base.std.in_progress = 0;
+}
+
+/**
+ * @brief Allocates chunk in a buffer for one entry and injects overflow if
+ * there is no room for requested entry.
+ *
+ * @param content_len Number of 32bit arguments. In case of allocating for hex dump it
+ * is the size of the buffer in 32bit words (ceiled).
+ * @param p_wr_idx Pointer to write index.
+ *
+ * @return True if successful allocation, false otherwise.
+ *
+ */
+static inline bool buf_prealloc(uint32_t content_len, uint32_t * p_wr_idx, bool std)
+{
+ uint32_t req_len = content_len + HEADER_SIZE;
+ bool ret = true;
+ CRITICAL_REGION_ENTER();
+ *p_wr_idx = m_log_data.wr_idx;
+ uint32_t available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ while (req_len > available_words)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_log_data.log_dropped_cnt, 1));
+ if (NRF_LOG_ALLOW_OVERFLOW)
+ {
+ uint32_t dropped_in_skip = log_skip();
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_log_data.log_dropped_cnt, dropped_in_skip));
+ available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ }
+ else
+ {
+ ret = false;
+ break;
+ }
+ }
+
+ if (ret)
+ {
+ nrf_log_main_header_t invalid_header;
+ invalid_header.raw = 0;
+
+ if (std)
+ {
+ invalid_header.std.type = HEADER_TYPE_STD;
+ invalid_header.std.in_progress = 1;
+ invalid_header.std.nargs = content_len;
+ }
+ else
+ {
+ invalid_header.hexdump.type = HEADER_TYPE_HEXDUMP;
+ invalid_header.hexdump.in_progress = 1;
+ invalid_header.hexdump.len = content_len;
+ }
+
+ nrf_log_main_header_t * p_header = (nrf_log_main_header_t *)&m_log_data.buffer[m_log_data.wr_idx & m_log_data.mask];
+
+ p_header->raw = invalid_header.raw;
+
+ m_log_data.wr_idx += req_len;
+ }
+
+ CRITICAL_REGION_EXIT();
+ return ret;
+}
+
+
+/**
+ * @brief Function for preallocating a continuous chunk of memory from circular buffer.
+ *
+ * If buffer does not fit starting from current position it will be allocated at
+ * the beginning of the circular buffer and offset will be returned indicating
+ * how much memory has been ommited at the end of the buffer. Function is
+ * using critical section.
+ *
+ * @param len32 Length of buffer to allocate. Given in words.
+ * @param p_offset Offset of the buffer.
+ * @param p_wr_idx Pointer to write index.
+ *
+ * @return A pointer to the allocated buffer. NULL if allocation failed.
+ */
+static inline uint32_t * cont_buf_prealloc(uint32_t len32,
+ uint32_t * p_offset,
+ uint32_t * p_wr_idx)
+{
+ //allocation algorithm relies on that assumption
+ STATIC_ASSERT(PUSHED_HEADER_SIZE == 1);
+ uint32_t * p_buf = NULL;
+
+ len32 += PUSHED_HEADER_SIZE; // Increment because 32bit header is needed to be stored.
+
+ CRITICAL_REGION_ENTER();
+ *p_wr_idx = m_log_data.wr_idx;
+ uint32_t available_words = (m_log_data.mask + 1) -
+ (m_log_data.wr_idx - m_log_data.rd_idx);
+ uint32_t tail_words = (m_log_data.mask + 1) - (m_log_data.wr_idx & m_log_data.mask);
+
+ //available space is continuous
+ uint32_t curr_pos_available = (available_words <= tail_words) ? available_words : tail_words;
+ uint32_t start_pos_available = (available_words <= tail_words) ? 0 : (available_words - tail_words);
+
+ if ((len32 <= curr_pos_available) ||
+ ((len32 - PUSHED_HEADER_SIZE) <= start_pos_available))
+ {
+ // buffer will fit in the tail or in the begining
+ // non zero offset is set if string is put at the beginning of the buffer
+ *p_offset = (len32 <= curr_pos_available) ? 0 : (tail_words - PUSHED_HEADER_SIZE);
+ uint32_t str_start_idx =
+ (m_log_data.wr_idx + PUSHED_HEADER_SIZE + *p_offset) & m_log_data.mask;
+ p_buf = &m_log_data.buffer[str_start_idx];
+ // index is incremented by payload and offset
+ m_log_data.wr_idx += (len32 + *p_offset);
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ return p_buf;
+}
+
+
+uint32_t nrf_log_push(char * const p_str)
+{
+ if ((m_log_data.autoflush) || (p_str == NULL))
+ {
+ return (uint32_t)p_str;
+ }
+
+ uint32_t mask = m_log_data.mask;
+ uint32_t slen = strlen(p_str) + 1;
+ uint32_t buflen = CEIL_DIV(slen, sizeof(uint32_t));
+ uint32_t offset = 0;
+ uint32_t wr_idx;
+ char * p_dst_str = (char *)cont_buf_prealloc(buflen, &offset, &wr_idx);
+ if (p_dst_str)
+ {
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
+ PUSHED_HEADER_FILL(p_header, offset, buflen);
+ memcpy(p_dst_str, p_str, slen);
+ }
+ return (uint32_t)p_dst_str;
+}
+
+static inline void std_n(uint32_t severity_mid, char const * const p_str, uint32_t const * args, uint32_t nargs)
+{
+ uint32_t mask = m_log_data.mask;
+ uint32_t wr_idx;
+
+ if (buf_prealloc(nargs, &wr_idx, true))
+ {
+ // Proceed only if buffer was successfully preallocated.
+
+ uint32_t data_idx = wr_idx + HEADER_SIZE;
+ uint32_t i;
+ for (i = 0; i < nargs; i++)
+ {
+ m_log_data.buffer[data_idx++ & mask] =args[i];
+ }
+ std_header_set(severity_mid, p_str, nargs, wr_idx, mask);
+ }
+ if (m_log_data.autoflush)
+ {
+ NRF_LOG_FLUSH();
+ }
+
+}
+
+void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str)
+{
+ std_n(severity_mid, p_str, NULL, 0);
+}
+
+
+void nrf_log_frontend_std_1(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0)
+{
+ uint32_t args[] = {val0};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_2(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1)
+{
+ uint32_t args[] = {val0, val1};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_3(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2)
+{
+ uint32_t args[] = {val0, val1, val2};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_4(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3)
+{
+ uint32_t args[] = {val0, val1, val2, val3};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_5(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4)
+{
+ uint32_t args[] = {val0, val1, val2, val3, val4};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_6(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4,
+ uint32_t val5)
+{
+ uint32_t args[] = {val0, val1, val2, val3, val4, val5};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_hexdump(uint32_t severity_mid,
+ const void * const p_data,
+ uint16_t length)
+{
+ uint32_t mask = m_log_data.mask;
+
+ uint32_t wr_idx;
+ if (buf_prealloc(CEIL_DIV(length, sizeof(uint32_t)), &wr_idx, false))
+ {
+ uint32_t header_wr_idx = wr_idx;
+ wr_idx += HEADER_SIZE;
+
+ uint32_t space0 = sizeof(uint32_t) * (m_log_data.mask + 1 - (wr_idx & mask));
+ if (length <= space0)
+ {
+ memcpy(&m_log_data.buffer[wr_idx & mask], p_data, length);
+ }
+ else
+ {
+ memcpy(&m_log_data.buffer[wr_idx & mask], p_data, space0);
+ memcpy(&m_log_data.buffer[0], &((uint8_t *)p_data)[space0], length - space0);
+ }
+
+ //Prepare header - in reverse order to ensure that packet type is validated (set to HEXDUMP as last action)
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.buffer[(header_wr_idx + 2) & mask] = m_log_data.timestamp_func();
+ }
+
+ uint32_t module_id = severity_mid >> NRF_LOG_MODULE_ID_POS;
+ uint32_t dropped = dropped_sat16_get();
+ m_log_data.buffer[(header_wr_idx + 1) & mask] = module_id | (dropped << 16);
+ //Header prepare
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[header_wr_idx & mask];
+ p_header->base.hexdump.severity = severity_mid & NRF_LOG_LEVEL_MASK;
+ p_header->base.hexdump.offset = 0;
+ p_header->base.hexdump.len = length;
+ p_header->base.hexdump.type = HEADER_TYPE_HEXDUMP;
+ p_header->base.hexdump.in_progress = 0;
+
+
+
+ }
+
+ if (m_log_data.autoflush)
+ {
+ NRF_LOG_FLUSH();
+ }
+}
+
+
+bool buffer_is_empty(void)
+{
+ return (m_log_data.rd_idx == m_log_data.wr_idx);
+}
+
+bool nrf_log_frontend_dequeue(void)
+{
+
+ if (buffer_is_empty())
+ {
+ return false;
+ }
+ m_log_data.log_skipped = 0;
+ //It has to be ensured that reading rd_idx occurs after skipped flag is cleared.
+ __DSB();
+ uint32_t rd_idx = m_log_data.rd_idx;
+ uint32_t mask = m_log_data.mask;
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_log_header_t header;
+ nrf_memobj_t * p_msg_buf = NULL;
+ uint32_t memobj_offset = 0;
+ uint32_t severity = 0;
+
+ // Skip any string that is pushed to the circular buffer.
+ do {
+ if (invalid_packets_pushed_str_omit(p_header, &rd_idx))
+ {
+ //Check if end of data is not reached.
+ if (rd_idx >= m_log_data.wr_idx)
+ {
+ m_log_data.rd_idx = m_log_data.wr_idx;
+ return false;
+ }
+ //something was omitted. Point to new header and try again.
+ p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+
+ uint32_t i;
+ for (i = 0; i < HEADER_SIZE; i++)
+ {
+ ((uint32_t*)&header)[i] = m_log_data.buffer[rd_idx++ & mask];
+ }
+
+ if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t orig_data_len = header.base.hexdump.len;
+ uint32_t data_len = MIN(header.base.hexdump.len, NRF_LOG_MAX_HEXDUMP); //limit the data
+ header.base.hexdump.len = data_len;
+ uint32_t msg_buf_size8 = sizeof(uint32_t)*HEADER_SIZE + data_len;
+ severity = header.base.hexdump.severity;
+ p_msg_buf = nrf_memobj_alloc(&log_mempool, msg_buf_size8);
+
+ if (p_msg_buf)
+ {
+ nrf_memobj_get(p_msg_buf);
+ nrf_memobj_write(p_msg_buf, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset += HEADER_SIZE*sizeof(uint32_t);
+
+ uint32_t space0 = sizeof(uint32_t) * (mask + 1 - (rd_idx & mask));
+ if (data_len > space0)
+ {
+ uint8_t * ptr0 = space0 ?
+ (uint8_t *)&m_log_data.buffer[rd_idx & mask] :
+ (uint8_t *)&m_log_data.buffer[0];
+ uint8_t len0 = space0 ? space0 : data_len;
+ uint8_t * ptr1 = space0 ?
+ (uint8_t *)&m_log_data.buffer[0] : NULL;
+ uint8_t len1 = space0 ? data_len - space0 : 0;
+
+ nrf_memobj_write(p_msg_buf, ptr0, len0, memobj_offset);
+ memobj_offset += len0;
+ if (ptr1)
+ {
+ nrf_memobj_write(p_msg_buf, ptr1, len1, memobj_offset);
+ }
+ }
+ else
+ {
+ uint8_t * p_data = (uint8_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_memobj_write(p_msg_buf, p_data, data_len, memobj_offset);
+ }
+ rd_idx += CEIL_DIV(orig_data_len, 4);
+ }
+ }
+ else if (header.base.generic.type == HEADER_TYPE_STD) // standard entry
+ {
+ header.base.std.nargs = MIN(header.base.std.nargs, NRF_LOG_MAX_NUM_OF_ARGS);
+ uint32_t msg_buf_size32 = HEADER_SIZE + header.base.std.nargs;
+ severity = header.base.std.severity;
+
+ p_msg_buf = nrf_memobj_alloc(&log_mempool, msg_buf_size32*sizeof(uint32_t));
+
+ if (p_msg_buf)
+ {
+ nrf_memobj_get(p_msg_buf);
+ nrf_memobj_write(p_msg_buf, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset += HEADER_SIZE*sizeof(uint32_t);
+
+ for (i = 0; i < header.base.std.nargs; i++)
+ {
+ nrf_memobj_write(p_msg_buf, &m_log_data.buffer[rd_idx++ & mask],
+ sizeof(uint32_t), memobj_offset);
+ memobj_offset += sizeof(uint32_t);
+ }
+ }
+ }
+ else
+ {
+ //Do nothing. In case of log overflow buffer can contain corrupted data.
+ }
+
+ if (p_msg_buf)
+ {
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ if (NRF_LOG_ALLOW_OVERFLOW && m_log_data.log_skipped)
+ {
+ // Check if any log was skipped during log processing. Do not forward log if skipping
+ // occured because data may be invalid.
+ nrf_memobj_put(p_msg_buf);
+ }
+ else
+ {
+ while (p_backend)
+ {
+ bool entry_accepted = false;
+ if (nrf_log_backend_is_enabled(p_backend) == true)
+ {
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint8_t backend_id = nrf_log_backend_id_get(p_backend);
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(header.module_id);
+ uint32_t filter_lvls = p_module_filter->filter_lvls;
+ uint32_t backend_lvl = (filter_lvls >> (backend_id*NRF_LOG_LEVEL_BITS))
+ & NRF_LOG_LEVEL_MASK;
+ //Degrade INFO_RAW level to INFO.
+ severity = (severity == NRF_LOG_SEVERITY_INFO_RAW) ? NRF_LOG_SEVERITY_INFO : severity;
+ if (backend_lvl >= severity)
+ {
+ entry_accepted = true;
+ }
+ }
+ else
+ {
+ (void)severity;
+ entry_accepted = true;
+ }
+ }
+ if (entry_accepted)
+ {
+ nrf_log_backend_put(p_backend, p_msg_buf);
+ }
+ p_backend = p_backend->p_next;
+ }
+
+ nrf_memobj_put(p_msg_buf);
+
+ if (NRF_LOG_ALLOW_OVERFLOW)
+ {
+ // Read index can be moved forward only if dequeueing process was not interrupt by
+ // skipping procedure. If NRF_LOG_ALLOW_OVERFLOW is set then in case of buffer gets full
+ // and new logger entry occurs, oldest entry is removed. In that case read index is
+ // changed and updating it here would corrupt the internal circular buffer.
+ CRITICAL_REGION_ENTER();
+ if (m_log_data.log_skipped == 0)
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+ else
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+ }
+ }
+ else
+ {
+ //Could not allocate memobj - backends are not freeing them on time.
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ //Flush all backends
+ while (p_backend)
+ {
+ nrf_log_backend_flush(p_backend);
+ p_backend = p_backend->p_next;
+ }
+ NRF_LOG_WARNING("Backends flushed");
+ }
+
+ return buffer_is_empty() ? false : true;
+}
+
+static int32_t backend_id_assign(void)
+{
+ int32_t candidate_id;
+ nrf_log_backend_t * p_backend;
+ bool id_available;
+ for (candidate_id = 0; candidate_id < NRF_LOG_MAX_BACKENDS; candidate_id++)
+ {
+ p_backend = m_log_data.p_backend_head;
+ id_available = true;
+ while (p_backend)
+ {
+ if (nrf_log_backend_id_get(p_backend) == candidate_id)
+ {
+ id_available = false;
+ break;
+ }
+ p_backend = p_backend->p_next;
+ }
+ if (id_available)
+ {
+ return candidate_id;
+ }
+ }
+ return -1;
+}
+
+int32_t nrf_log_backend_add(nrf_log_backend_t * p_backend, nrf_log_severity_t severity)
+{
+ int32_t id = backend_id_assign();
+ if (id == -1)
+ {
+ return id;
+ }
+
+ nrf_log_backend_id_set(p_backend, id);
+ //add to list
+ if (m_log_data.p_backend_head == NULL)
+ {
+ m_log_data.p_backend_head = p_backend;
+ p_backend->p_next = NULL;
+ }
+ else
+ {
+ p_backend->p_next = m_log_data.p_backend_head->p_next;
+ m_log_data.p_backend_head->p_next = p_backend;
+ }
+
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint32_t i;
+ for (i = 0; i < nrf_log_module_cnt_get(); i++)
+ {
+ nrf_log_severity_t buildin_lvl = nrf_log_module_init_filter_get(i);
+ nrf_log_severity_t actual_severity = MIN(buildin_lvl, severity);
+ nrf_log_module_filter_set(nrf_log_backend_id_get(p_backend), i, actual_severity);
+ }
+ }
+
+ return id;
+}
+
+void nrf_log_backend_remove(nrf_log_backend_t * p_backend)
+{
+ nrf_log_backend_t * p_curr = m_log_data.p_backend_head;
+ nrf_log_backend_t * p_prev = NULL;
+ while (p_curr != p_backend)
+ {
+ p_prev = p_curr;
+ p_curr = p_curr->p_next;
+ }
+
+ if (p_prev)
+ {
+ p_prev->p_next = p_backend->p_next;
+ }
+ else
+ {
+ m_log_data.p_backend_head = NULL;
+ }
+}
+
+void nrf_log_panic(void)
+{
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ m_log_data.autoflush = true;
+ while (p_backend)
+ {
+ nrf_log_backend_enable(p_backend);
+ nrf_log_backend_panic_set(p_backend);
+ p_backend = p_backend->p_next;
+ }
+}
+
+#if NRF_LOG_CLI_CMDS
+#include "nrf_cli.h"
+
+static const char * m_severity_lvls[] = {
+ "none",
+ "error",
+ "warning",
+ "info",
+ "debug",
+};
+
+static const char * m_severity_lvls_sorted[] = {
+ "debug",
+ "error",
+ "info",
+ "none",
+ "warning",
+};
+
+static void log_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t modules_cnt = nrf_log_module_cnt_get();
+ uint32_t backend_id = p_cli->p_log_backend->backend.id;
+ uint32_t i;
+
+ if (!nrf_log_backend_is_enabled(&p_cli->p_log_backend->backend))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Logs are halted!\r\n");
+ }
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%-40s | current | built-in \r\n", "module_name");
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "----------------------------------------------------------\r\n");
+ for (i = 0; i < modules_cnt; i++)
+ {
+ nrf_log_severity_t module_dynamic_lvl = nrf_log_module_filter_get(backend_id, i, true, true);
+ nrf_log_severity_t module_compiled_lvl = nrf_log_module_filter_get(backend_id, i, true, false);
+ nrf_log_severity_t actual_compiled_lvl = MIN(module_compiled_lvl, (nrf_log_severity_t)NRF_LOG_DEFAULT_LEVEL);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%-40s | %-7s | %s%s\r\n",
+ nrf_log_module_name_get(i, true),
+ m_severity_lvls[module_dynamic_lvl],
+ m_severity_lvls[actual_compiled_lvl],
+ actual_compiled_lvl < module_compiled_lvl ? "*" : "");
+ }
+}
+
+static bool module_id_get(const char * p_name, uint32_t * p_id)
+{
+ uint32_t modules_cnt = nrf_log_module_cnt_get();
+ const char * p_tmp_name;
+ uint32_t j;
+ for (j = 0; j < modules_cnt; j++)
+ {
+ p_tmp_name = nrf_log_module_name_get(j, false);
+ if (strncmp(p_tmp_name, p_name, 32) == 0)
+ {
+ *p_id = j;
+ break;
+ }
+ }
+ return (j != modules_cnt);
+}
+
+static bool module_id_filter_set(uint32_t backend_id,
+ uint32_t module_id,
+ nrf_log_severity_t lvl)
+{
+ nrf_log_severity_t buildin_lvl = nrf_log_module_filter_get(backend_id, module_id, false, false);
+ if (lvl > buildin_lvl)
+ {
+ return false;
+ }
+ else
+ {
+ nrf_log_module_filter_set(backend_id, module_id, lvl);
+ return true;
+ }
+}
+
+static void log_ctrl(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t backend_id = p_cli->p_log_backend->backend.id;
+ nrf_log_severity_t lvl;
+ uint32_t first_m_name_idx;
+ uint32_t i;
+ bool all_modules = false;
+
+ if (argc > 0)
+ {
+ if (strncmp(argv[0], "enable", 7) == 0)
+ {
+ if (argc == 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad parameter count.\r\n");
+ return;
+ }
+
+ if (argc == 2)
+ {
+ all_modules = true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(m_severity_lvls); i++)
+ {
+ if (strncmp(argv[1], m_severity_lvls[i], 10) == 0)
+ {
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(m_severity_lvls))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown severity level: %s\r\n", argv[1]);
+ return;
+ }
+
+ lvl = (nrf_log_severity_t)i;
+ first_m_name_idx = 2;
+
+ }
+ else if (strncmp(argv[0], "disable", 8) == 0)
+ {
+ if (argc == 1)
+ {
+ all_modules = true;
+ }
+ lvl = NRF_LOG_SEVERITY_NONE;
+ first_m_name_idx = 1;
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown option: %s\r\n", argv[0]);
+ return;
+ }
+
+ if (all_modules)
+ {
+ for (i = 0; i < nrf_log_module_cnt_get(); i++)
+ {
+ if (module_id_filter_set(backend_id, i, lvl) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Level unavailable for module: %s\r\n", nrf_log_module_name_get(i, false));
+ }
+ }
+ }
+ else
+ {
+ for (i = first_m_name_idx; i < argc; i++)
+ {
+ uint32_t module_id = 0;
+ if (module_id_get(argv[i], &module_id) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown module:%s\r\n", argv[i]);
+ }
+
+ if (module_id_filter_set(backend_id, module_id, lvl) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Level unavailable for module: %s\r\n", nrf_log_module_name_get(module_id, false));
+ }
+ }
+ }
+ }
+}
+static void module_name_get(size_t idx, nrf_cli_static_entry_t * p_static);
+
+NRF_CLI_CREATE_DYNAMIC_CMD(m_module_name, module_name_get);
+
+static void module_name_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ p_static->handler = NULL;
+ p_static->p_help = NULL;
+ p_static->p_subcmd = &m_module_name;
+ p_static->p_syntax = nrf_log_module_name_get(idx, true);
+}
+
+static void severity_lvl_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ p_static->handler = NULL;
+ p_static->p_help = NULL;
+ p_static->p_subcmd = &m_module_name;
+ p_static->p_syntax = (idx < ARRAY_SIZE(m_severity_lvls_sorted)) ?
+ m_severity_lvls_sorted[idx] : NULL;
+}
+
+NRF_CLI_CREATE_DYNAMIC_CMD(m_severity_lvl, severity_lvl_get);
+
+static void log_halt(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ nrf_log_backend_disable(&p_cli->p_log_backend->backend);
+}
+
+static void log_go(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ nrf_log_backend_enable(&p_cli->p_log_backend->backend);
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_log_stat)
+{
+ NRF_CLI_CMD(disable, &m_module_name,
+ "'log disable <module_0> .. <module_n>' disables logs in specified "
+ "modules (all if no modules specified).",
+ log_ctrl),
+ NRF_CLI_CMD(enable, &m_severity_lvl,
+ "'log enable <level> <module_0> ... <module_n>' enables logs up to given level in "
+ "specified modules (all if no modules specified).",
+ log_ctrl),
+ NRF_CLI_CMD(go, NULL, "Resume logging", log_go),
+ NRF_CLI_CMD(halt, NULL, "Halt logging", log_halt),
+ NRF_CLI_CMD(status, NULL, "Logger status", log_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+static void log_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s:%s%s\r\n", argv[0], " unknown parameter: ", argv[1]);
+}
+
+NRF_CLI_CMD_REGISTER(log, &m_sub_log_stat, "Commands for controlling logger", log_cmd);
+
+#endif //NRF_LOG_CLI_CMDS
+
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h
new file mode 100644
index 0000000..7c5246f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h
@@ -0,0 +1,529 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_LOG_INTERNAL_H__
+#define NRF_LOG_INTERNAL_H__
+#include "sdk_common.h"
+#include "nrf.h"
+#include "nrf_error.h"
+#include "app_util.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log_instance.h"
+#include "nrf_log_types.h"
+
+#ifndef NRF_LOG_ERROR_COLOR
+ #define NRF_LOG_ERROR_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_WARNING_COLOR
+ #define NRF_LOG_WARNING_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_INFO_COLOR
+ #define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_DEBUG_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 0
+#endif
+
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+
+#ifndef NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_FILTERS_ENABLED 0
+#endif
+
+#ifndef NRF_LOG_MODULE_NAME
+ #define NRF_LOG_MODULE_NAME app
+#endif
+
+#define NRF_LOG_LEVEL_BITS 3
+#define NRF_LOG_LEVEL_MASK ((1UL << NRF_LOG_LEVEL_BITS) - 1)
+#define NRF_LOG_MODULE_ID_BITS 16
+#define NRF_LOG_MODULE_ID_POS 16
+
+
+#define NRF_LOG_MAX_NUM_OF_ARGS 6
+
+
+#if NRF_LOG_FILTERS_ENABLED && NRF_LOG_ENABLED
+ #define NRF_LOG_FILTER NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).filter
+ #define NRF_LOG_INST_FILTER(p_inst) (p_inst)->filter
+#else
+ #undef NRF_LOG_FILTER
+ #define NRF_LOG_FILTER NRF_LOG_SEVERITY_DEBUG
+ #define NRF_LOG_INST_FILTER(p_inst) NRF_LOG_SEVERITY_DEBUG
+#endif
+
+#if NRF_LOG_ENABLED
+#define NRF_LOG_MODULE_ID NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).module_id
+#define NRF_LOG_INST_ID(p_inst) (p_inst)->module_id
+#else
+#define NRF_LOG_MODULE_ID 0
+#define NRF_LOG_INST_ID(p_inst) 0
+#endif
+
+
+#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__)
+#define LOG_INTERNAL(type, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \
+ __VA_ARGS__), type, __VA_ARGS__)
+#if NRF_LOG_ENABLED
+#define NRF_LOG_INTERNAL_LOG_PUSH(_str) nrf_log_push(_str)
+#define LOG_INTERNAL_0(type, str) \
+ nrf_log_frontend_std_0(type, str)
+#define LOG_INTERNAL_1(type, str, arg0) \
+ /*lint -save -e571*/nrf_log_frontend_std_1(type, str, (uint32_t)(arg0))/*lint -restore*/
+#define LOG_INTERNAL_2(type, str, arg0, arg1) \
+ /*lint -save -e571*/nrf_log_frontend_std_2(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1))/*lint -restore*/
+#define LOG_INTERNAL_3(type, str, arg0, arg1, arg2) \
+ /*lint -save -e571*/nrf_log_frontend_std_3(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2))/*lint -restore*/
+#define LOG_INTERNAL_4(type, str, arg0, arg1, arg2, arg3) \
+ /*lint -save -e571*/nrf_log_frontend_std_4(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3))/*lint -restore*/
+#define LOG_INTERNAL_5(type, str, arg0, arg1, arg2, arg3, arg4) \
+ /*lint -save -e571*/nrf_log_frontend_std_5(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4))/*lint -restore*/
+#define LOG_INTERNAL_6(type, str, arg0, arg1, arg2, arg3, arg4, arg5) \
+ /*lint -save -e571*/nrf_log_frontend_std_6(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4), (uint32_t)(arg5))/*lint -restore*/
+
+
+#else //NRF_LOG_ENABLED
+#define NRF_LOG_INTERNAL_LOG_PUSH(_str) (void)(_str)
+#define LOG_INTERNAL_0(_type, _str) \
+ (void)(_type); (void)(_str)
+#define LOG_INTERNAL_1(_type, _str, _arg0) \
+ (void)(_type); (void)(_str); (void)(_arg0)
+#define LOG_INTERNAL_2(_type, _str, _arg0, _arg1) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1)
+#define LOG_INTERNAL_3(_type, _str, _arg0, _arg1, _arg2) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2)
+#define LOG_INTERNAL_4(_type, _str, _arg0, _arg1, _arg2, _arg3) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3)
+#define LOG_INTERNAL_5(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4)
+#define LOG_INTERNAL_6(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4, _arg5) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4); (void)(_arg5)
+#endif //NRF_LOG_ENABLED
+
+#define LOG_SEVERITY_MOD_ID(severity) ((severity) | NRF_LOG_MODULE_ID << NRF_LOG_MODULE_ID_POS)
+#define LOG_SEVERITY_INST_ID(severity,p_inst) ((severity) | NRF_LOG_INST_ID(p_inst) << NRF_LOG_MODULE_ID_POS)
+
+#if NRF_LOG_ENABLED
+#define LOG_HEXDUMP(_severity, _p_data, _length) \
+ nrf_log_frontend_hexdump((_severity), (_p_data), (_length))
+#else
+#define LOG_HEXDUMP(_severity, _p_data, _length) \
+ (void)(_severity); (void)(_p_data); (void)_length
+#endif
+
+#define NRF_LOG_INTERNAL_INST(level, level_id, p_inst, ...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_INST_FILTER(p_inst) >= level) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_INST_ID(level_id, p_inst), __VA_ARGS__); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_MODULE(level, level_id, ...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= level) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(level_id), __VA_ARGS__); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST(level, level_id, p_inst, p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_INST_FILTER(p_inst) >= level) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_INST_ID(level_id, p_inst), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_HEXDUMP_MODULE(level, level_id, p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= level) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(level_id), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_INST_ERROR(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_ERROR(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR,__VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_data, len)
+
+#define NRF_LOG_INTERNAL_INST_WARNING(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_WARNING(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING,__VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_data, len)
+
+#define NRF_LOG_INTERNAL_INST_INFO(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_INFO(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_data, len)
+
+#define NRF_LOG_INTERNAL_RAW_INFO(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, p_data, len)
+
+#define NRF_LOG_INTERNAL_INST_DEBUG(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_DEBUG(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_data, len)
+
+
+#if NRF_LOG_ENABLED
+
+#ifdef UNIT_TEST
+#define COMPILED_LOG_LEVEL 4
+#else
+#define COMPILED_LOG_LEVEL NRF_LOG_LEVEL
+#endif
+
+
+#define NRF_LOG_INTERNAL_MODULE_REGISTER() \
+ NRF_LOG_INTERNAL_ITEM_REGISTER(NRF_LOG_MODULE_NAME, \
+ STRINGIFY(NRF_LOG_MODULE_NAME), \
+ NRF_LOG_INFO_COLOR, \
+ NRF_LOG_DEBUG_COLOR, \
+ NRF_LOG_INITIAL_LEVEL, \
+ COMPILED_LOG_LEVEL)
+
+#else
+#define NRF_LOG_INTERNAL_MODULE_REGISTER() /*lint -save -e19*/ /*lint -restore*/
+#endif
+
+extern NRF_LOG_DYNAMIC_STRUCT_NAME NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME);
+
+/**
+ * Set of macros for encoding and decoding header for log entries.
+ * There are 3 types of entries:
+ * 1. Standard entry (STD)
+ * An entry consists of header, pointer to string and values. Header contains
+ * severity leveland determines number of arguments and thus size of the entry.
+ * Since flash address space starts from 0x00000000 and is limited to kB rather
+ * than MB 22 bits are used to store the address (4MB). It is used that way to
+ * save one RAM memory.
+ *
+ * --------------------------------
+ * |TYPE|SEVERITY|NARGS| P_STR |
+ * |------------------------------|
+ * | Module_ID (optional) |
+ * |------------------------------|
+ * | TIMESTAMP (optional) |
+ * |------------------------------|
+ * | ARG0 |
+ * |------------------------------|
+ * | .... |
+ * |------------------------------|
+ * | ARG(nargs-1) |
+ * --------------------------------
+ *
+ * 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of
+ * header, optional timestamp, pointer to string and data. A header contains
+ * length (10bit) and offset which is updated after backend processes part of
+ * data.
+ *
+ * --------------------------------
+ * |TYPE|SEVERITY|NARGS|OFFSET|LEN|
+ * |------------------------------|
+ * | Module_ID (optional) |
+ * |------------------------------|
+ * | TIMESTAMP (optional) |
+ * |------------------------------|
+ * | P_STR |
+ * |------------------------------|
+ * | data |
+ * |------------------------------|
+ * | data | dummy |
+ * --------------------------------
+ *
+ * 3. Pushed string. If string is pushed into the logger internal buffer it is
+ * stored as PUSHED entry. It consists of header, unused data (optional) and
+ * string. Unused data is present if string does not not fit into a buffer
+ * without wrapping (and string cannot be wrapped). In that case header
+ * contains information about offset.
+ *
+ * --------------------------------
+ * |TYPE| OFFSET | LEN |
+ * |------------------------------|
+ * | OFFSET |
+ * |------------------------------|
+ * end| OFFSET |
+ * 0|------------------------------|
+ * | STRING |
+ * |------------------------------|
+ * | STRING | dummy |
+ * --------------------------------
+ */
+
+#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U)
+#define HEADER_TYPE_STD 1U
+#define HEADER_TYPE_HEXDUMP 2U
+#define HEADER_TYPE_PUSHED 0U
+#define HEADER_TYPE_INVALID 3U
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t in_progress: 1;
+ uint32_t data : 29;
+} nrf_log_generic_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t in_progress: 1;
+ uint32_t severity : 3;
+ uint32_t nargs : 4;
+ uint32_t addr : 22;
+} nrf_log_std_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t in_progress: 1;
+ uint32_t severity : 3;
+ uint32_t offset : 10;
+ uint32_t reserved : 6;
+ uint32_t len : 10;
+} nrf_log_hexdump_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t reserved0 : 4;
+ uint32_t offset : 10;
+ uint32_t reserved1 : 6;
+ uint32_t len : 10;
+} nrf_log_pushed_header_t;
+
+typedef union
+{
+ nrf_log_generic_header_t generic;
+ nrf_log_std_header_t std;
+ nrf_log_hexdump_header_t hexdump;
+ nrf_log_pushed_header_t pushed;
+ uint32_t raw;
+} nrf_log_main_header_t;
+
+typedef struct
+{
+ nrf_log_main_header_t base;
+ uint16_t module_id;
+ uint16_t dropped;
+ uint32_t timestamp;
+} nrf_log_header_t;
+
+#define HEADER_SIZE (sizeof(nrf_log_header_t)/sizeof(uint32_t) - \
+ (NRF_LOG_USES_TIMESTAMP ? 0 : 1))
+
+#define PUSHED_HEADER_SIZE (sizeof(nrf_log_pushed_header_t)/sizeof(uint32_t))
+
+//Implementation assumes that pushed header has one word.
+STATIC_ASSERT(PUSHED_HEADER_SIZE == 1);
+/**
+ * @brief A function for logging raw string.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a string.
+ */
+void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str);
+
+/**
+ * @brief A function for logging a formatted string with one argument.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0 An argument.
+ */
+void nrf_log_frontend_std_1(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0);
+
+/**
+ * @brief A function for logging a formatted string with 2 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_2(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1);
+
+/**
+ * @brief A function for logging a formatted string with 3 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_3(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2);
+
+/**
+ * @brief A function for logging a formatted string with 4 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_4(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3);
+
+/**
+ * @brief A function for logging a formatted string with 5 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3, val4 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_5(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4);
+
+/**
+ * @brief A function for logging a formatted string with 6 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3, val4, val5 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_6(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4,
+ uint32_t val5);
+
+/**
+ * @brief A function for logging raw data.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a string which is prefixing the data.
+ * @param p_data A pointer to data to be dumped.
+ * @param length Length of data (in bytes).
+ *
+ */
+void nrf_log_frontend_hexdump(uint32_t severity_mid,
+ const void * const p_data,
+ uint16_t length);
+
+/**
+ * @brief A function for reading a byte from log backend.
+ *
+ * @return Byte.
+ */
+uint8_t nrf_log_getchar(void);
+#endif // NRF_LOG_INTERNAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c
new file mode 100644
index 0000000..fa548f3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_fprintf.h"
+#include <ctype.h>
+
+#define NRF_LOG_COLOR_CODE_DEFAULT "\x1B[0m"
+#define NRF_LOG_COLOR_CODE_BLACK "\x1B[1;30m"
+#define NRF_LOG_COLOR_CODE_RED "\x1B[1;31m"
+#define NRF_LOG_COLOR_CODE_GREEN "\x1B[1;32m"
+#define NRF_LOG_COLOR_CODE_YELLOW "\x1B[1;33m"
+#define NRF_LOG_COLOR_CODE_BLUE "\x1B[1;34m"
+#define NRF_LOG_COLOR_CODE_MAGENTA "\x1B[1;35m"
+#define NRF_LOG_COLOR_CODE_CYAN "\x1B[1;36m"
+#define NRF_LOG_COLOR_CODE_WHITE "\x1B[1;37m"
+
+static const char * severity_names[] = {
+ NULL,
+ "error",
+ "warning",
+ "info",
+ "debug"
+};
+
+static const char * m_colors[] = {
+ NRF_LOG_COLOR_CODE_DEFAULT,
+ NRF_LOG_COLOR_CODE_BLACK,
+ NRF_LOG_COLOR_CODE_RED,
+ NRF_LOG_COLOR_CODE_GREEN,
+ NRF_LOG_COLOR_CODE_YELLOW,
+ NRF_LOG_COLOR_CODE_BLUE,
+ NRF_LOG_COLOR_CODE_MAGENTA,
+ NRF_LOG_COLOR_CODE_CYAN,
+ NRF_LOG_COLOR_CODE_WHITE,
+};
+
+static uint32_t m_freq;
+static uint32_t m_timestamp_div;
+
+static void timestamp_print(nrf_fprintf_ctx_t * p_ctx, uint32_t timestamp)
+{
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ if (NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED)
+ {
+ timestamp /= m_timestamp_div;
+ uint32_t seconds = timestamp/m_freq;
+ uint32_t hours = seconds/3600;
+ seconds -= hours * 3600;
+ uint32_t mins = seconds/60;
+ seconds -= mins * 60;
+
+ uint32_t reminder = timestamp % m_freq;
+ uint32_t ms = (reminder * 1000)/m_freq;
+ uint32_t us = (1000*(1000*reminder - (ms * m_freq)))/m_freq;
+
+ nrf_fprintf(p_ctx, "[%02d:%02d:%02d.%03d,%03d] ", hours, mins, seconds, ms, us);
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, "[%08lu] ", timestamp);
+ }
+ }
+}
+static void prefix_process(nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ if (p_params->dropped)
+ {
+ nrf_fprintf(p_ctx,
+ "%sLogs dropped (%d)%s\r\n",
+ NRF_LOG_COLOR_CODE_RED,
+ p_params->dropped,
+ NRF_LOG_COLOR_CODE_DEFAULT);
+ }
+
+ if (!(p_params->severity == NRF_LOG_SEVERITY_INFO_RAW))
+ {
+ if (p_params->use_colors)
+ {
+ nrf_fprintf(p_ctx, "%s",
+ m_colors[nrf_log_color_id_get( p_params->module_id, p_params->severity)]);
+ }
+ timestamp_print(p_ctx, p_params->timestamp);
+
+ nrf_fprintf(p_ctx, "<%s> %s: ",
+ severity_names[p_params->severity], nrf_log_module_name_get(p_params->module_id, false));
+ }
+}
+
+static void postfix_process(nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx,
+ bool newline)
+{
+ if (!(p_params->severity == NRF_LOG_SEVERITY_INFO_RAW))
+ {
+ if (p_params->use_colors)
+ {
+ nrf_fprintf(p_ctx, "%s", m_colors[0]);
+ }
+ nrf_fprintf(p_ctx, "\r\n");
+ }
+ else if (newline)
+ {
+ nrf_fprintf(p_ctx, "\r\n");
+ }
+ nrf_fprintf_buffer_flush(p_ctx);
+}
+
+void nrf_log_std_entry_process(char const * p_str,
+ uint32_t const * p_args,
+ uint32_t nargs,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ bool auto_flush = p_ctx->auto_flush;
+ p_ctx->auto_flush = false;
+
+ prefix_process(p_params, p_ctx);
+
+ switch (nargs)
+ {
+ case 0:
+ nrf_fprintf(p_ctx, p_str);
+ break;
+ case 1:
+ nrf_fprintf(p_ctx, p_str, p_args[0]);
+ break;
+ case 2:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1]);
+ break;
+ case 3:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2]);
+ break;
+ case 4:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3]);
+ break;
+ case 5:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4]);
+ break;
+ case 6:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5]);
+ break;
+
+ default:
+ break;
+ }
+
+ postfix_process(p_params, p_ctx, false);
+ p_ctx->auto_flush = auto_flush;
+}
+
+#define HEXDUMP_BYTES_IN_LINE 8
+
+void nrf_log_hexdump_entry_process(uint8_t * p_data,
+ uint32_t data_len,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ if (data_len > HEXDUMP_BYTES_IN_LINE)
+ {
+ return;
+ }
+ bool auto_flush = p_ctx->auto_flush;
+ p_ctx->auto_flush = false;
+
+ prefix_process(p_params, p_ctx);
+
+ uint32_t i;
+
+ for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
+ {
+ if (i < data_len)
+ {
+ nrf_fprintf(p_ctx, " %02x", p_data[i]);
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, " ");
+ }
+ }
+ nrf_fprintf(p_ctx, "|");
+
+ for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
+ {
+ if (i < data_len)
+ {
+ char c = (char)p_data[i];
+ nrf_fprintf(p_ctx, "%c", isprint((int)c) ? c :'.');
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, " ");
+ }
+ }
+
+ postfix_process(p_params, p_ctx, true);
+
+ p_ctx->auto_flush = auto_flush;
+}
+
+void nrf_log_str_formatter_timestamp_freq_set(uint32_t freq)
+{
+ m_timestamp_div = 1;
+ /* There is no point to have frequency higher than 1MHz (ns are not printed) and too high
+ * frequency leads to overflows in calculations.
+ */
+ while (freq > 1000000)
+ {
+ freq /= 2;
+ m_timestamp_div *= 2;
+ }
+ m_freq = freq;
+}
+#endif //NRF_LOG_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c
new file mode 100644
index 0000000..44b44fc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c
@@ -0,0 +1,231 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_memobj.h"
+#include "nrf_atomic.h"
+#include "nrf_assert.h"
+
+typedef struct memobj_elem_s memobj_elem_t;
+
+typedef struct
+{
+ memobj_elem_t * p_next;
+} memobj_header_t;
+
+typedef struct
+{
+ uint8_t user_cnt;
+ uint8_t chunk_cnt;
+ uint16_t chunk_size;
+} memobj_head_header_fields_t;
+
+typedef struct
+{
+ union
+ {
+ nrf_atomic_u32_t atomic_user_cnt;
+ memobj_head_header_fields_t fields;
+ } data;
+} memobj_head_header_t;
+
+typedef struct
+{
+ memobj_header_t header;
+ memobj_head_header_t head_header;
+ uint8_t data[1];
+} memobj_head_t;
+
+STATIC_ASSERT(sizeof(memobj_header_t) == NRF_MEMOBJ_STD_HEADER_SIZE);
+
+struct memobj_elem_s
+{
+ memobj_header_t header;
+ uint8_t data[1];
+};
+
+ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool)
+{
+ return nrf_balloc_init((nrf_balloc_t const *)p_pool);
+}
+
+nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
+ size_t size)
+{
+ uint32_t bsize = (uint32_t)NRF_BALLOC_ELEMENT_SIZE((nrf_balloc_t const *)p_pool) - sizeof(memobj_header_t);
+ uint8_t num_of_chunks = (uint8_t)CEIL_DIV(size + sizeof(memobj_head_header_t), bsize);
+
+ memobj_head_t * p_head = nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
+ if (p_head == NULL)
+ {
+ return NULL;
+ }
+ p_head->head_header.data.fields.user_cnt = 0;
+ p_head->head_header.data.fields.chunk_cnt = 1;
+ p_head->head_header.data.fields.chunk_size = bsize;
+
+ memobj_header_t * p_prev = (memobj_header_t *)p_head;
+ memobj_header_t * p_curr;
+ uint32_t i;
+ uint32_t chunk_less1 = (uint32_t)num_of_chunks - 1;
+
+ p_prev->p_next = (memobj_elem_t *)p_pool;
+ for (i = 0; i < chunk_less1; i++)
+ {
+ p_curr = (memobj_header_t *)nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
+ if (p_curr)
+ {
+ (p_head->head_header.data.fields.chunk_cnt)++;
+ p_prev->p_next = (memobj_elem_t *)p_curr;
+ p_curr->p_next = (memobj_elem_t *)p_pool;
+ p_prev = p_curr;
+ }
+ else
+ {
+ //Couldn't allocate all requested buffers
+ nrf_memobj_free((nrf_memobj_t *)p_head);
+ return NULL;
+ }
+ }
+ return (nrf_memobj_t *)p_head;
+}
+
+void nrf_memobj_free(nrf_memobj_t * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint8_t chunk_cnt = p_head->head_header.data.fields.chunk_cnt;
+ uint32_t i;
+ memobj_header_t * p_curr = (memobj_header_t *)p_obj;
+ memobj_header_t * p_next;
+ uint32_t chunk_less1 = (uint32_t)chunk_cnt - 1;
+
+ for (i = 0; i < chunk_less1; i++)
+ {
+ p_curr = (memobj_header_t *)p_curr->p_next;
+ }
+ nrf_balloc_t const * p_pool2 = (nrf_balloc_t const *)p_curr->p_next;
+
+ p_curr = (memobj_header_t *)p_obj;
+ for (i = 0; i < chunk_cnt; i++)
+ {
+ p_next = (memobj_header_t *)p_curr->p_next;
+ nrf_balloc_free(p_pool2, p_curr);
+ p_curr = p_next;
+ }
+}
+
+void nrf_memobj_get(nrf_memobj_t const * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ (void)nrf_atomic_u32_add(&p_head->head_header.data.atomic_user_cnt, 1);
+}
+
+void nrf_memobj_put(nrf_memobj_t * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint32_t user_cnt = nrf_atomic_u32_sub(&p_head->head_header.data.atomic_user_cnt, 1);
+ memobj_head_header_fields_t * p_fields = (memobj_head_header_fields_t *)&user_cnt;
+ if (p_fields->user_cnt == 0)
+ {
+ nrf_memobj_free(p_obj);
+ }
+}
+
+static void memobj_op(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset,
+ bool read)
+{
+
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint32_t space_in_chunk = p_head->head_header.data.fields.chunk_size;
+ memobj_elem_t * p_curr_chunk = (memobj_elem_t *)p_obj;
+ uint32_t chunk_idx = (offset + sizeof(memobj_head_header_fields_t))/space_in_chunk;
+ uint32_t chunk_offset = (offset + sizeof(memobj_head_header_fields_t)) % space_in_chunk;
+
+ uint8_t chunks_expected = CEIL_DIV((offset + sizeof(memobj_head_header_fields_t) + len),
+ space_in_chunk);
+ UNUSED_VARIABLE(chunks_expected);
+ ASSERT(p_head->head_header.data.fields.chunk_cnt >= chunks_expected);
+
+ while (chunk_idx > 0)
+ {
+ p_curr_chunk = p_curr_chunk->header.p_next;
+ chunk_idx--;
+ }
+
+ uint32_t src_offset = 0;
+ uint32_t curr_cpy_size = space_in_chunk-chunk_offset;
+ curr_cpy_size = curr_cpy_size > len ? len : curr_cpy_size;
+
+ while (len)
+ {
+ if (read)
+ {
+ memcpy(&((uint8_t *)p_data)[src_offset], &p_curr_chunk->data[chunk_offset], curr_cpy_size);
+ }
+ else
+ {
+ memcpy(&p_curr_chunk->data[chunk_offset], &((uint8_t *)p_data)[src_offset], curr_cpy_size);
+ }
+ chunk_offset = 0;
+ p_curr_chunk = p_curr_chunk->header.p_next;
+ len -= curr_cpy_size;
+ src_offset += curr_cpy_size;
+ curr_cpy_size = (space_in_chunk > len) ? len : space_in_chunk;
+ }
+}
+
+void nrf_memobj_write(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset)
+{
+
+ memobj_op(p_obj, p_data, len, offset, false);
+}
+
+void nrf_memobj_read(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset)
+{
+ memobj_op(p_obj, p_data, len, offset, true);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h
new file mode 100644
index 0000000..06740db
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h
@@ -0,0 +1,198 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_MEMOBJ_H
+#define NRF_MEMOBJ_H
+
+/**
+* @defgroup nrf_memobj Memory Object module
+* @{
+* @ingroup app_common
+* @brief Functions for controlling memory object
+*/
+#include <stdint.h>
+#include <stdlib.h>
+#include "sdk_errors.h"
+#include "nrf_balloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Memory object can consist of multiple object with the same size. Each object has header and data
+ * part. First element in memory object is memory object head which has special header, remaining objects
+ * has the same header. Model of memory object is presented below.
+ *
+ * |---------------------| |---------------------| |---------------------|
+ * | head header (u32): | --->| std header - p_next |------->| p_memobj_pool |
+ * | num_of_chunks, | | |---------------------| |---------------------|
+ * | ref counter | | | | | |
+ * |---------------------| | | | | |
+ * | std header - p_next |-| | | .... | |
+ * |---------------------| | data | | data |
+ * | | | | | |
+ * | data | | | | |
+ * | | | | | |
+ * |---------------------| |---------------------| |---------------------|
+ * head mid_element last_element
+ *
+ *
+ */
+#define NRF_MEMOBJ_STD_HEADER_SIZE sizeof(uint32_t)
+
+/**
+ * @brief Macro for creating a nrf_memobj pool.
+ *
+ * Macro declares nrf_balloc object. Element in the pool contains user defined data part and
+ * memobj header.
+ */
+#define NRF_MEMOBJ_POOL_DEF(_name, _element_size, _pool_size) \
+ NRF_BALLOC_DEF(_name, ((_element_size)+NRF_MEMOBJ_STD_HEADER_SIZE), (_pool_size))
+
+/**
+ * @brief Pool of memobj.
+ */
+typedef nrf_balloc_t nrf_memobj_pool_t;
+
+/**
+ * @brief Memobj handle.
+ */
+typedef void * nrf_memobj_t;
+
+/**
+ * @brief Function for initializing the memobj pool instance.
+ *
+ * This function initializes the pool.
+ *
+ * @param[in] p_pool Pointer to the memobj pool instance structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool);
+
+/**
+ * @brief Function for allocating memobj with requested size.
+ *
+ * Fixed length elements in the pool are linked together to provide amount of memory requested by
+ * the user. If memory object is successfully allocated then user can use memory however it is
+ * fragmented into multiple object so it has to be access through the API: @ref nrf_memobj_write,
+ * @ref nrf_memobj_read.
+ *
+ * This function initializes the pool.
+ *
+ * @param[in] p_pool Pointer to the memobj pool instance structure.
+ * @param[in] size Data size of requested object.
+ *
+ * @return Pointer to memory object or NULL if requested size cannot be allocated.
+ */
+nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
+ size_t size);
+
+/**
+ * @brief Function for indicating that memory object is used and cannot be freed.
+ *
+ * Memory object can be shared and reused between multiple modules and this mechanism ensures that
+ * object is freed when no longer used by any module. Memory object has a counter which is incremented
+ * whenever this function is called. @ref nrf_memobj_put function decrements the counter.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_get(nrf_memobj_t const * p_obj);
+
+
+/**
+ * @brief Function for indicated that memory object is no longer used by the module and can be freed
+ * if no other module is using it.
+ *
+ * Memory object is returned to the pool if internal counter reaches 0 after decrementing. It means
+ * that no other module is needing it anymore.
+ *
+ * @note Memory object holds pointer to the pool which was used to allocate it so it does not have
+ * to be provided explicitly to this function.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_put(nrf_memobj_t * p_obj);
+
+
+/**
+ * @brief Function for forcing freeing of the memory object.
+ *
+ * @note This function should be use with caution because it can lead to undefined behavior of the
+ * modules since modules using the memory object are not aware that it has been freed.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_free(nrf_memobj_t * p_obj);
+
+/**
+ * @brief Function for writing data to the memory object.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ * @param[in] p_data Pointer to data to be written to the memory object.
+ * @param[in] len Amount of data to be written to the memory object.
+ * @param[in] offset Offset.
+ */
+void nrf_memobj_write(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset);
+
+/**
+ * @brief Function for reading data from the memory object.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ * @param[in] p_data Pointer to the destination buffer.
+ * @param[in] len Amount of data to be read from the memory object.
+ * @param[in] offset Offset.
+ */
+void nrf_memobj_read(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_MEMOBJ_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c
new file mode 100644
index 0000000..9db2aef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c
@@ -0,0 +1,442 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_mpu.h"
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#if NRF_MPU_CLI_CMDS
+#include "nrf_cli.h"
+#endif
+
+#define NRF_LOG_MODULE_NAME nrf_mpu
+
+#if NRF_MPU_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_MPU_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_MPU_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_MPU_CONFIG_DEBUG_COLOR
+#else
+#define NRF_LOG_LEVEL 0
+#endif
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+// Check module requirements.
+STATIC_ASSERT(__MPU_PRESENT);
+STATIC_ASSERT(__CORTEX_M == 4);
+
+/**@brief Return number of unified regions avaiable in MPU. */
+__STATIC_INLINE unsigned int nrf_mpu_get_number_of_regions(void)
+{
+ return (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
+}
+
+/**@brief Extract human-readable memory type from attributes. */
+static const char *nrf_mpu_mem_type(uint32_t attributes)
+{
+ attributes &= MPU_RASR_TEX_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk;
+
+ switch (attributes)
+ {
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Strongly-ordered, Shareable";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Device, Shareable";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "Normal";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Normal, Shareable";
+
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Device";
+
+ default:
+ if (((attributes & MPU_RASR_TEX_Msk) >> MPU_RASR_TEX_Pos) >= 0x04)
+ {
+ return (attributes & MPU_RASR_S_Msk) ? "Normal, Shareable" : "Normal";
+ }
+ else
+ {
+ return "Reserved or Implementation Defined";
+ }
+ }
+
+ // Not reached.
+}
+
+/**@brief Extract human-readable access level from attributes. */
+static const char *nrf_mpu_mem_access(uint32_t attributes)
+{
+ switch ((attributes & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos)
+ {
+ case 0x00:
+ return "--/--";
+
+ case 0x01:
+ return "RW/--";
+
+ case 0x02:
+ return "RW/RO";
+
+ case 0x03:
+ return "RW/RW";
+
+ case 0x04:
+ return "\?\?/\?\?";
+
+ case 0x05:
+ return "RO/--";
+
+ case 0x06:
+ case 0x07:
+ return "RO/RO";
+
+ default:
+ return "Unknown";
+ }
+
+ // Not reached.
+}
+
+ret_code_t nrf_mpu_init(void)
+{
+ unsigned int i, regions;
+
+ // Make sure that MPU uses unified regions. Separate are not supported.
+ if ((MPU->TYPE & MPU_TYPE_SEPARATE_Msk) >> MPU_TYPE_SEPARATE_Pos)
+ {
+ NRF_LOG_ERROR("Non-unified MPU is not supported!");
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ // Make sure that we can handle all avaiable regions.
+ regions = nrf_mpu_get_number_of_regions();
+ if (regions > ((1 << (8 * sizeof(nrf_mpu_region_t))) - 1))
+ {
+ NRF_LOG_ERROR("MPU with %u regions is not supported!", regions);
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ // Disable MPU.
+ MPU->CTRL = 0;
+
+ // Clear all regions.
+ for (i = 0; i < regions; i++)
+ {
+ MPU->RNR = i;
+ MPU->RASR = 0;
+ MPU->RBAR = 0;
+ }
+
+ /* Enable MPU */
+ MPU->CTRL = (1 << MPU_CTRL_ENABLE_Pos) |
+ (1 << MPU_CTRL_PRIVDEFENA_Pos);
+
+ // Make sure that configuration changes are active.
+ __DSB();
+
+ NRF_LOG_INFO("MPU Initalized. %u unified regions avaiable.", regions);
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_mpu_region_create(nrf_mpu_region_t *p_region,
+ void *address,
+ size_t size,
+ uint32_t attributes)
+{
+ unsigned long addr = (unsigned long)(address);
+ unsigned int i, regions = nrf_mpu_get_number_of_regions();
+
+ // Size must be power of 2 greather than or equal to 32
+ if ((size & (size - 1)) || (size < 32))
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: Region size is not valid!", addr, addr + size - 1);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Region must be aligned to it's size.
+ if (addr & (size - 1))
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: Region alignment is not valid!", addr, addr + size - 1);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Check if attributes are valid.
+ if (attributes & ~MPU_RASR_ATTRS_Msk)
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: Region attributes are not valid!", addr, addr + size - 1);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ NRF_LOG_DEBUG("MPU region creating (location: 0x%08X-0x%08X)",
+ addr,
+ addr + size - 1);
+ // Create region.
+ CRITICAL_REGION_ENTER();
+ for (i = 0; i < regions; i++)
+ {
+ MPU->RNR = i;
+ if (MPU->RASR & MPU_RASR_ENABLE_Msk)
+ {
+ continue;
+ }
+
+ MPU->RBAR = addr;
+ MPU->RASR = attributes |
+ (1 << MPU_RASR_ENABLE_Pos) |
+ ((31 - __CLZ(size) - 1) << MPU_RASR_SIZE_Pos);
+
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (i >= regions)
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: No free region found!", addr, addr + size - 1);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Apply changes.
+ __DSB();
+
+ // Save region number;
+ *p_region = i;
+
+ NRF_LOG_DEBUG("MPU region %u created (location: 0x%08X-0x%08X, access: %s, type: %s, flags: %s).",
+ i,
+ addr,
+ addr + size - 1,
+ (uint32_t)nrf_mpu_mem_access(attributes),
+ (uint32_t)nrf_mpu_mem_type(attributes),
+ (uint32_t)((attributes & MPU_RASR_XN_Msk) ? "XN" : "--"));
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_mpu_region_destroy(nrf_mpu_region_t region)
+{
+ if (region >= nrf_mpu_get_number_of_regions())
+ {
+ NRF_LOG_ERROR("Cannot destroy MPU region %u: Invaid region!", region);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ CRITICAL_REGION_ENTER();
+ MPU->RNR = region;
+ MPU->RASR = 0;
+ MPU->RBAR = 0;
+ CRITICAL_REGION_EXIT();
+
+ // Apply changes.
+ __DSB();
+
+ NRF_LOG_DEBUG("MPU region %u destroyed.", region);
+
+ return NRF_SUCCESS;
+}
+
+#if NRF_MPU_CLI_CMDS
+
+/**@brief Extract human-readable caching policy from attributes. */
+static const char *nrf_mpu_mem_caching(uint32_t attributes)
+{
+ static const char *caching[] =
+ {
+ "--/--", "WBWA/--", "WT/--", "WB/--",
+ "--/WBWA", "WBWA/WBWA","WT/WBWA", "WB/WBWA",
+ "--/WT", "WBWA/WT", "WT/WT", "WB/WT",
+ "--/WB", "WBWA/WB", "WT/WB", "WB/WB",
+ };
+
+ uint32_t tex = (attributes & MPU_RASR_TEX_Msk) >> MPU_RASR_TEX_Pos;
+ uint32_t c = (attributes & MPU_RASR_C_Msk) >> MPU_RASR_C_Pos;
+ uint32_t b = (attributes & MPU_RASR_B_Msk) >> MPU_RASR_B_Pos;
+
+ attributes &= MPU_RASR_TEX_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk;
+
+ switch (attributes)
+ {
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "--/--";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "WT/WT";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "WB/WB";
+
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "WBWA/WBWA";
+
+ default:
+ if (tex >= 0x04)
+ {
+ return caching[((tex & 0x03) << 2) | ((c & 0x01) << 1) | (b & 0x01)];
+ }
+ break;
+ }
+
+ return "Unknown";
+}
+/**@brief Implementation of "mpu info" command. */
+static void nrf_mpu_cmd_info(nrf_cli_t const *p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ unsigned int i, regions = nrf_mpu_get_number_of_regions();
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU State: %s, %u unified regions aviable.\r\n\r\n",
+ (MPU->CTRL & MPU_CTRL_ENABLE_Msk) ? "Enabled" : "Disabled",
+ regions);
+
+
+ for (i = 0; i < regions; i++)
+ {
+ uint32_t rasr, rbar;
+ uint32_t size;
+
+ CRITICAL_REGION_ENTER();
+ MPU->RNR = i;
+ rasr = MPU->RASR;
+ rbar = MPU->RBAR;
+ CRITICAL_REGION_EXIT();
+
+ if ((rasr & MPU_RASR_ENABLE_Msk) == 0)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Region %u: Disabled\r\n", i);
+ continue;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Region %u: Enabled\r\n", i);
+
+ size = 1ul << (((rasr & MPU_RASR_SIZE_Msk) >> MPU_RASR_SIZE_Pos) + 1);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Location:\t0x%08X-0x%08X (size: %u bytes)\r\n",
+ rbar,
+ rbar + size - 1,
+ size);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Access:\t%s\r\n", nrf_mpu_mem_access(rasr));
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Type:\t\t%s\r\n", nrf_mpu_mem_type(rasr));
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Caching:\t%s\r\n", nrf_mpu_mem_caching(rasr));
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Flags:\t%s\r\n\r\n", (rasr & MPU_RASR_XN_Msk) ? "XN" : "--");
+ }
+}
+
+/**@brief Implementation of "mpu dump" command. */
+static void nrf_mpu_cmd_dump(nrf_cli_t const *p_cli, size_t argc, char **argv)
+{
+ unsigned int i, regions = nrf_mpu_get_number_of_regions();
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU_TYPE:\t0x%08X\r\n", MPU->TYPE);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU_CTRL:\t0x%08X\r\n", MPU->CTRL);
+
+ for (i = 0; i < regions; i++)
+ {
+ uint32_t rasr, rbar;
+
+ CRITICAL_REGION_ENTER();
+ MPU->RNR = i;
+ rasr = MPU->RASR;
+ rbar = MPU->RBAR;
+ CRITICAL_REGION_EXIT();
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\r\nMPU_RBAR[%u]:\t0x%08X\r\n", i, rbar);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU_RASR[%u]:\t0x%08X\r\n", i, rasr);
+ }
+}
+
+/**@brief Implementation of "mpu" command. */
+static void nrf_mpu_cmd_unknown(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s: unknown parameter: %s\r\n", argv[0], argv[1]);
+}
+
+// Register "mpu" command and it's subcommands in CLI.
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_mpu_commands)
+{
+ NRF_CLI_CMD(dump, NULL, "Dump MPU registers.", nrf_mpu_cmd_dump),
+ NRF_CLI_CMD(info, NULL, "Print information about MPU state.", nrf_mpu_cmd_info),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(mpu, &nrf_mpu_commands, "Commands for MPU management", nrf_mpu_cmd_unknown);
+
+#endif //NRF_MPU_CLI_CMDS
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h
new file mode 100644
index 0000000..2ba309f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __NRF_MPU_H
+#define __NRF_MPU_H
+
+/**
+* @defgroup nrf_mpu MPU (Memory Protection Unit) driver
+* @{
+* @ingroup app_common
+* @brief Functions for controlling MPU
+*/
+#include <stdint.h>
+#include <stdlib.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief MPU region handle. */
+typedef uint8_t nrf_mpu_region_t;
+
+/**@brief Initialize MPU and driver.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_mpu_init(void);
+
+/**@brief Create new MPU region.
+ *
+ * @param[out] p_region Region handle.
+ * @param[in] address Region base address.
+ * @param[in] size Region size,
+ * @param[in] attributes Region attributes.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_mpu_region_create(nrf_mpu_region_t *p_region,
+ void *address,
+ size_t size,
+ uint32_t attributes);
+
+/**@brief Destroy MPU region.
+ *
+ * @param[in] region Region handle.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_mpu_region_destroy(nrf_mpu_region_t region);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NRF_MPU_H */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c
new file mode 100644
index 0000000..0198179
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c
@@ -0,0 +1,238 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_ringbuf.h"
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+
+#define WR_OFFSET 0
+#define RD_OFFSET 1
+
+void nrf_ringbuf_init(nrf_ringbuf_t const * p_ringbuf)
+{
+ p_ringbuf->p_cb->wr_idx = 0;
+ p_ringbuf->p_cb->rd_idx = 0;
+ p_ringbuf->p_cb->tmp_rd_idx = 0;
+ p_ringbuf->p_cb->tmp_wr_idx = 0;
+ p_ringbuf->p_cb->rd_flag = 0;
+ p_ringbuf->p_cb->wr_flag = 0;
+}
+
+ret_code_t nrf_ringbuf_alloc(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start)
+{
+ ASSERT(pp_data);
+ ASSERT(p_length);
+
+ if (start)
+ {
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->wr_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+
+ if (p_ringbuf->p_cb->tmp_wr_idx - p_ringbuf->p_cb->rd_idx == p_ringbuf->bufsize_mask + 1)
+ {
+ *p_length = 0;
+ if (start)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->wr_flag));
+ }
+ return NRF_SUCCESS;
+ }
+
+ uint32_t wr_idx = p_ringbuf->p_cb->tmp_wr_idx & p_ringbuf->bufsize_mask;
+ uint32_t rd_idx = p_ringbuf->p_cb->rd_idx & p_ringbuf->bufsize_mask;
+ uint32_t available = (wr_idx >= rd_idx) ? p_ringbuf->bufsize_mask + 1 - wr_idx :
+ p_ringbuf->p_cb->rd_idx - p_ringbuf->p_cb->tmp_wr_idx;
+ *p_length = *p_length < available ? *p_length : available;
+
+ *pp_data = &p_ringbuf->p_buffer[wr_idx];
+ p_ringbuf->p_cb->tmp_wr_idx += *p_length;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_put(nrf_ringbuf_t const * p_ringbuf, size_t length)
+{
+ uint32_t available = p_ringbuf->bufsize_mask + 1 -
+ (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
+ if (length > available)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_ringbuf->p_cb->wr_idx += length;
+ p_ringbuf->p_cb->tmp_wr_idx = p_ringbuf->p_cb->wr_idx;
+ if (nrf_atomic_flag_clear_fetch(&p_ringbuf->p_cb->wr_flag) == 0)
+ {
+ /* Flag was already cleared. Suggests misuse. */
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_cpy_put(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t const * p_data,
+ size_t * p_length)
+{
+ ASSERT(p_data);
+ ASSERT(p_length);
+
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->wr_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint32_t available = p_ringbuf->bufsize_mask + 1 -
+ (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
+ *p_length = available > *p_length ? *p_length : available;
+ size_t length = *p_length;
+ uint32_t masked_wr_idx = (p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask);
+ uint32_t trail = p_ringbuf->bufsize_mask + 1 - masked_wr_idx;
+
+ if (length > trail)
+ {
+ memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, trail);
+ length -= trail;
+ masked_wr_idx = 0;
+ p_data += trail;
+ }
+ memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, length);
+ p_ringbuf->p_cb->wr_idx += *p_length;
+
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->wr_flag));
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_get(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start)
+{
+ ASSERT(pp_data);
+ ASSERT(p_length);
+
+ if (start)
+ {
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->rd_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+
+ uint32_t available = p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->tmp_rd_idx;
+ if (available == 0)
+ {
+ *p_length = 0;
+ if (start)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
+ }
+ return NRF_SUCCESS;
+ }
+
+ uint32_t masked_tmp_rd_idx = p_ringbuf->p_cb->tmp_rd_idx & p_ringbuf->bufsize_mask;
+ uint32_t masked_wr_idx = p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask;
+
+ if ((masked_wr_idx > masked_tmp_rd_idx) && (available < *p_length))
+ {
+ *p_length = available;
+ }
+ else if (masked_wr_idx <= masked_tmp_rd_idx)
+ {
+ uint32_t trail = p_ringbuf->bufsize_mask + 1 - masked_tmp_rd_idx;
+ if (*p_length > trail)
+ {
+ *p_length = trail;
+ }
+ }
+ *pp_data = &p_ringbuf->p_buffer[masked_tmp_rd_idx];
+ p_ringbuf->p_cb->tmp_rd_idx += *p_length;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_cpy_get(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t * p_data,
+ size_t * p_length)
+{
+ ASSERT(p_data);
+ ASSERT(p_length);
+
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->rd_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint32_t available = p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx;
+ *p_length = available > *p_length ? *p_length : available;
+ size_t length = *p_length;
+ uint32_t masked_rd_idx = (p_ringbuf->p_cb->rd_idx & p_ringbuf->bufsize_mask);
+ uint32_t masked_wr_idx = (p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask);
+ uint32_t trail = (masked_wr_idx > masked_rd_idx) ? masked_wr_idx - masked_rd_idx :
+ p_ringbuf->bufsize_mask + 1 - masked_rd_idx;
+
+ if (length > trail)
+ {
+ memcpy(&p_ringbuf->p_buffer[masked_rd_idx], p_data, trail);
+ length -= trail;
+ masked_rd_idx = 0;
+ p_data += trail;
+ }
+ memcpy(p_data, &p_ringbuf->p_buffer[masked_rd_idx], length);
+ p_ringbuf->p_cb->rd_idx += *p_length;
+
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_free(nrf_ringbuf_t const * p_ringbuf, size_t length)
+{
+ uint32_t available = (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
+ if (length > available)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_ringbuf->p_cb->rd_idx += length;
+ p_ringbuf->p_cb->tmp_rd_idx = p_ringbuf->p_cb->rd_idx;
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h
new file mode 100644
index 0000000..0da5c73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_RINGBUF_H
+#define NRF_RINGBUF_H
+
+/**
+* @defgroup nrf_ringbuf Ring buffer
+* @{
+* @ingroup app_common
+* @brief Functions for controlling ring buffer.
+*/
+
+#include <stdint.h>
+#include "nrf_atomic.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @brief ring buffer instance control block.
+ * */
+typedef struct
+{
+ nrf_atomic_flag_t wr_flag; //!< Protection flag.
+ nrf_atomic_flag_t rd_flag; //!< Protection flag.
+ uint32_t wr_idx; //!< Write index (updated when putting).
+ uint32_t tmp_wr_idx; //!< Temporary write index (updated when allocating).
+ uint32_t rd_idx; //!< Read index (updated when freeing).
+ uint32_t tmp_rd_idx; //!< Temporary read index (updated when getting).
+} nrf_ringbuf_cb_t;
+
+/**
+ * @brief ring buffer instance structure.
+ * */
+typedef struct
+{
+ uint8_t * p_buffer; //!< Pointer to memory used by the ring buffer.
+ uint32_t bufsize_mask; //!< Buffer size mask (buffer size must be power of 2).
+ nrf_ringbuf_cb_t * p_cb; //!< Pointer to instance control block.
+} nrf_ringbuf_t;
+
+/**
+ * @brief Macro for defining a ring buffer instance.
+ *
+ * @param _name Instance name.
+ * @param _size Size of ring buffer (must be power of 2).
+ * */
+#define NRF_RINGBUF_DEF(_name, _size) \
+ STATIC_ASSERT(IS_POWER_OF_TWO(_size)); \
+ static uint8_t CONCAT_2(_name,_buf)[_size]; \
+ static nrf_ringbuf_cb_t CONCAT_2(_name,_cb); \
+ static const nrf_ringbuf_t _name = { \
+ .p_buffer = CONCAT_2(_name,_buf), \
+ .bufsize_mask = _size - 1, \
+ .p_cb = &CONCAT_2(_name,_cb), \
+ }
+
+/**
+ * @brief Initializes a ring buffer instance.
+ *
+ * @param p_ringbuf Pointer to Ring buffer instance.
+ *
+ * */
+void nrf_ringbuf_init(nrf_ringbuf_t const * p_ringbuf);
+
+/**
+ * @brief Function for allocating memory from a ring buffer.
+ *
+ * Function attempts to allocate amount of memory requested by the user, or smaller amount if
+ * requested amount is not available. If start flag is set then exclusive access to allocation
+ * is established. @ref nrf_ringbuf_put frees access to allocation. If start flag is not set then
+ * exclusive access check is omitted.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] pp_data Pointer to pointer to the allocated buffer.
+ * @param[in, out] p_length Pointer to length. Length is set to requested amount and filled
+ * by the function with actually allocated amount.
+ * @param[in] start Set to true if exclusive access should be controlled.
+ *
+ * @retval NRF_SUCCESS Successful allocation (can be smaller amount than requested).
+ * NRF_ERROR_BUSY Ring buffer allocation process (alloc-put) is ongoing.
+ *
+ * */
+ret_code_t nrf_ringbuf_alloc(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start);
+
+/**
+ * @brief Function for commiting data to a ring buffer.
+ *
+ * When allocated buffer (see @ref nrf_ringbuf_alloc) has been filled with data it must be committed
+ * to make it available for @ref nrf_ringbuf_get and @ref nrf_ringbuf_cpy_get. This function commits
+ * the data (can be smaller amount than allocated).
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] length Amount of bytes to put.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_put(nrf_ringbuf_t const * p_ringbuf, size_t length);
+
+/**
+ * @brief Function for copying data directly into the ring buffer.
+ *
+ * This function is copying user buffer to the ring buffer.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] p_data Pointer to the input buffer.
+ * @param[in, out] p_length Amount of bytes to copy. Amount of bytes copied.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_cpy_put(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t const* p_data,
+ size_t * p_length);
+
+
+/**
+ * Function for getting data from the ring buffer.
+ *
+ * Function attempts to get requested amount of data from the ring buffer. If start flag is set then
+ * exclusive access to getting data from the ring buffer is established. @ref nrf_ringbuf_free frees
+ * access to getting data from the ring buffer. If start flag is not set then
+ * exclusive access check is omitted.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] pp_data Pointer to pointer to the buffer with data.
+ * @param[in, out] p_length Pointer to length. Length is set to requested amount and filled
+ * by the function with actual amount.
+ * @param[in] start Set to true if exclusive access should be controlled.
+ *
+ * @retval NRF_SUCCESS Successful getting (can be smaller amount than requested).
+ * NRF_ERROR_BUSY Ring buffer getting process (get-free) is ongoing.
+ */
+ret_code_t nrf_ringbuf_get(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start);
+
+/**
+ * @brief Function for freeing buffer back to a ring buffer.
+ *
+ * When buffer with data taken from the ring buffer (see @ref nrf_ringbuf_get) has been processed it
+ * must be freed to make it available for further use. This function frees the buffer (can be smaller
+ * amount than get).
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] length Amount of bytes to free.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_free(nrf_ringbuf_t const * p_ringbuf, size_t length);
+
+/**
+ * @brief Function for copying data directly out of the ring buffer.
+ *
+ * This function is copying available data from the ring buffer to user buffer.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] p_data Pointer to the input buffer.
+ * @param[in, out] p_length Amount of bytes to copy. Amount of bytes copied.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_cpy_get(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t * p_data,
+ size_t * p_length);
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_RINGBUF_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h
new file mode 100644
index 0000000..62eda64
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_SECTION_H__
+#define NRF_SECTION_H__
+
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup section_vars Section variables
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Section variables.
+ */
+
+//lint -save -e27 -esym(526,*)
+
+#if defined(__ICCARM__)
+// Enable IAR language extensions
+#pragma language=extended
+#endif
+
+/**@brief Macro for obtaining the address of the beginning of a section.
+ *
+ * param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(section_name, $$Base)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(__start_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_START_ADDR(section_name) __section_begin(STRINGIFY(section_name))
+#endif
+
+
+/**@brief Macro for obtaining the address of the end of a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(section_name, $$Limit)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(__stop_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_END_ADDR(section_name) __section_end(STRINGIFY(section_name))
+#endif
+
+
+/**@brief Macro for retrieving the length of a given section, in bytes.
+ *
+ * @param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_LENGTH(section_name) \
+ ((size_t)NRF_SECTION_END_ADDR(section_name) - \
+ (size_t)NRF_SECTION_START_ADDR(section_name))
+
+
+/**@brief Macro for creating a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variables to be registered in the section.
+ *
+ * @warning Data type must be word aligned to prevent padding.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ extern data_type * CONCAT_2(section_name, $$Base); \
+ extern void * CONCAT_2(section_name, $$Limit)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ extern data_type * CONCAT_2(__start_, section_name); \
+ extern void * CONCAT_2(__stop_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ _Pragma(STRINGIFY(section = STRINGIFY(section_name)));
+
+#endif
+
+
+/**@brief Macro for declaring a variable and registering it in a section.
+ *
+ * @details Declares a variable and registers it in a named section. This macro ensures that the
+ * variable is not stripped away when using optimizations.
+ *
+ * @note The order in which variables are placed in a section is dependent on the order in
+ * which the linker script encounters the variables during linking.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] section_var Variable to register in the given section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ section_var __attribute__ ((section(STRINGIFY(section_name)))) __attribute__((used))
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ section_var __attribute__ ((section("." STRINGIFY(section_name)))) __attribute__((used))
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ __root section_var @ STRINGIFY(section_name)
+#endif
+
+
+/**@brief Macro for retrieving a variable from a 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 the size of the stored type. No
+ * padding can exist in the named section in between individual
+ * stored items or this macro will fail.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variable.
+ * @param[in] i Index of the variable in section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_ITEM_GET(section_name, data_type, i) \
+ ((data_type*)NRF_SECTION_START_ADDR(section_name) + (i))
+
+
+/**@brief Macro for getting the number of variables in a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variables in the section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_ITEM_COUNT(section_name, data_type) \
+ NRF_SECTION_LENGTH(section_name) / sizeof(data_type)
+
+/** @} */
+
+//lint -restore
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SECTION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c
new file mode 100644
index 0000000..ea8b02f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_SECTION_ITER)
+
+#include "nrf_section_iter.h"
+
+
+#if !defined(__GNUC__)
+static void nrf_section_iter_item_set(nrf_section_iter_t * p_iter)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_iter->p_set != NULL);
+ ASSERT(p_iter->p_section != NULL);
+
+ while (true)
+ {
+ if (p_iter->p_section == p_iter->p_set->p_last)
+ {
+ // End of the section set.
+ p_iter->p_item = NULL;
+ return;
+ }
+
+ if (p_iter->p_section->p_start != p_iter->p_section->p_end)
+ {
+ // Not empty section.
+ p_iter->p_item = p_iter->p_section->p_start;
+ return;
+ }
+
+ // Next section.
+ p_iter->p_section++;
+ }
+}
+#endif
+
+
+void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_set != NULL);
+
+ p_iter->p_set = p_set;
+
+#if defined(__GNUC__)
+ p_iter->p_item = p_iter->p_set->section.p_start;
+ if (p_iter->p_item == p_iter->p_set->section.p_end)
+ {
+ p_iter->p_item = NULL;
+ }
+#else
+ p_iter->p_section = p_set->p_first;
+ nrf_section_iter_item_set(p_iter);
+#endif
+}
+
+void nrf_section_iter_next(nrf_section_iter_t * p_iter)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_iter->p_set != NULL);
+
+ if (p_iter->p_item == NULL)
+ {
+ return;
+ }
+
+ p_iter->p_item = (void *)((size_t)(p_iter->p_item) + p_iter->p_set->item_size);
+
+#if defined(__GNUC__)
+ if (p_iter->p_item == p_iter->p_set->section.p_end)
+ {
+ p_iter->p_item = NULL;
+ }
+#else
+ ASSERT(p_iter->p_section != NULL);
+ // End of current section reached?
+ if (p_iter->p_item == p_iter->p_section->p_end)
+ {
+ p_iter->p_section++;
+ nrf_section_iter_item_set(p_iter);
+ }
+#endif
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_SECTION_ITER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h
new file mode 100644
index 0000000..2f9be61
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_SECTION_ITER_H__
+#define NRF_SECTION_ITER_H__
+
+#include <stddef.h>
+#include "nrf_section.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup nrf_section_iter Section variables iterator
+ * @ingroup app_common
+ * @{
+ */
+
+/**@brief Single section description structure. */
+typedef struct
+{
+ void * p_start; //!< Pointer to the start of section.
+ void * p_end; //!< Pointer to the end of section.
+} nrf_section_t;
+
+
+/**@brief Set of the sections description structure. */
+typedef struct
+{
+#if defined(__GNUC__)
+ nrf_section_t section; //!< Description of the set of sections.
+ /**<
+ * In case of GCC all sections in the set are sorted and
+ * placed in contiguous area, because they are treated as
+ * one section.
+ */
+#else
+ nrf_section_t const * p_first; //!< Pointer to the first section in the set.
+ nrf_section_t const * p_last; //!< Pointer to the last section in the set.
+#endif
+ size_t item_size; //!< Size of the single item in the section.
+} nrf_section_set_t;
+
+
+/**@brief Section iterator structure. */
+typedef struct
+{
+ nrf_section_set_t const * p_set; //!< Pointer to the appropriate section set.
+#if !defined(__GNUC__)
+ nrf_section_t const * p_section; //!< Pointer to the selected section.
+ /**<
+ * In case of GCC all sections in the set are sorted and
+ * placed in contiguous area, because they are treated
+ * as one section.
+ */
+#endif
+ void * p_item; //!< Pointer to the selected item in the section.
+} nrf_section_iter_t;
+
+
+/**@brief Create a set of sections.
+ *
+ * @note This macro reserves memory for the given set of sections.
+ *
+ * @details A set of sections, is an ordered collections of sections.
+ *
+ * @param[in] _name Name of the set.
+ * @param[in] _type Type of the elements stored in the sections.
+ * @param[in] _count Number of the sections in the set. This parameter is ignored in case of GCC.
+ * @hideinitializer
+ */
+#if defined(__GNUC__)
+
+#define NRF_SECTION_SET_DEF(_name, _type, _count) \
+ \
+ NRF_SECTION_DEF(_name, _type); \
+ static nrf_section_set_t const _name = \
+ { \
+ .section = \
+ { \
+ .p_start = NRF_SECTION_START_ADDR(_name), \
+ .p_end = NRF_SECTION_END_ADDR(_name), \
+ }, \
+ .item_size = sizeof(_type), \
+ }
+
+#else
+
+#define NRF_SECTION_SET_DEF(_name, _type, _count) \
+/*lint -save -emacro(14, MACRO_REPEAT_FOR*) */ \
+MACRO_REPEAT_FOR(_count, NRF_SECTION_DEF_, _name, _type) \
+static nrf_section_t const CONCAT_2(_name, _array)[] = \
+{ \
+ MACRO_REPEAT_FOR(_count, NRF_SECTION_SET_DEF_, _name) \
+}; \
+/*lint -restore */ \
+static nrf_section_set_t const _name = \
+{ \
+ .p_first = CONCAT_2(_name, _array), \
+ .p_last = CONCAT_2(_name, _array) + ARRAY_SIZE(CONCAT_2(_name, _array)), \
+ .item_size = sizeof(_type), \
+}
+
+#ifndef DOXYGEN
+#define NRF_SECTION_DEF_(_priority, _name, _type) \
+NRF_SECTION_DEF(CONCAT_2(_name, _priority), _type);
+
+#define NRF_SECTION_SET_DEF_(_priority, _name) \
+{ \
+ .p_start = NRF_SECTION_START_ADDR(CONCAT_2(_name, _priority)), \
+ .p_end = NRF_SECTION_END_ADDR(CONCAT_2(_name, _priority)), \
+},
+#endif // DOXYGEN
+#endif // __GNUC__
+
+
+/**@brief Macro to declare a variable and register it in the section set.
+ *
+ * @note The order of the section in the set is based on the priority. The order with which
+ * variables are placed in a section is dependant on the order with which the linker
+ * encouters the variables during linking.
+ *
+ * @param[in] _name Name of the section set.
+ * @param[in] _priority Priority of the desired section.
+ * @param[in] _var The variable to register in the given section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_SET_ITEM_REGISTER(_name, _priority, _var) \
+ NRF_SECTION_ITEM_REGISTER(CONCAT_2(_name, _priority), _var)
+
+
+/**@brief Function for initializing the section set iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ * @param[in] p_set Pointer to the sections set.
+ */
+void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set);
+
+
+/**@brief Function for incrementing iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ */
+void nrf_section_iter_next(nrf_section_iter_t * p_iter);
+
+
+/**@brief Function for getting the element pointed to by the iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ *
+ * @retval Pointer to the element or NULL if iterator points end of the set.
+ */
+static inline void * nrf_section_iter_get(nrf_section_iter_t const * p_iter)
+{
+ ASSERT(p_iter);
+ return p_iter->p_item;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SECTION_ITER_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c
new file mode 100644
index 0000000..344da2f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_assert.h"
+#include "nrf_strerror.h"
+#include "nrf_mpu.h"
+#include "nrf_stack_guard.h"
+
+#define NRF_LOG_MODULE_NAME stack_guard
+
+#if NRF_STACK_GUARD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_STACK_GUARD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_STACK_GUARD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_STACK_GUARD_CONFIG_DEBUG_COLOR
+#endif
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if NRF_STACK_GUARD_ENABLED
+STATIC_ASSERT(STACK_GUARD_SIZE >= 32);
+
+ret_code_t nrf_stack_guard_init(void)
+{
+ nrf_mpu_region_t region;
+ uint32_t attributes;
+ ret_code_t status;
+
+ ASSERT((STACK_GUARD_BASE + STACK_GUARD_SIZE) < (uint32_t)((void *)(STACK_TOP)));
+
+ attributes = (0x05 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_B_Pos) | /* Normal memory, WBWA/WBWA */
+ (0x07 << MPU_RASR_AP_Pos) | (1 << MPU_RASR_XN_Pos); /* Access: RO/RO, XN */
+
+ status = nrf_mpu_region_create(&region,
+ (void *)(STACK_GUARD_BASE),
+ STACK_GUARD_SIZE,
+ attributes);
+
+ if (status == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("Stack Guard: 0x%08X-0x%08X (usable stack area: %u bytes)",
+ STACK_GUARD_BASE,
+ STACK_GUARD_BASE + STACK_GUARD_SIZE - 1,
+ REAL_STACK_SIZE);
+ }
+ else
+ {
+ NRF_LOG_ERROR("Cannot create stack guard page! Error: %u [%s]", status, (uint32_t)nrf_strerror_get(status));
+ }
+
+ return status;
+}
+
+#endif /* NRF_STACK_GUARD_ENABLED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h
new file mode 100644
index 0000000..d5f9f18
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __NRF_STACK_GUARD_H__
+#define __NRF_STACK_GUARD_H__
+
+/**
+* @defgroup nrf_stack_guard Stack guard
+* @{
+* @ingroup app_common
+* @brief Functions for enabling stack violation control
+*/
+#include "sdk_config.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_STACK_GUARD_ENABLED
+#define STACK_GUARD_SIZE (1ul << NRF_STACK_GUARD_CONFIG_SIZE)
+#define STACK_GUARD_BASE (((uint32_t)((void *)(STACK_BASE)) + STACK_GUARD_SIZE - 1) \
+ & ~(STACK_GUARD_SIZE - 1))
+#define REAL_STACK_SIZE (((int32_t)(STACK_TOP)) - (int32_t)(STACK_GUARD_BASE + STACK_GUARD_SIZE))
+#else /* !NRF_STACK_GUARD_ENABLED */
+#define REAL_STACK_SIZE (((int32_t)(STACK_TOP)) - (int32_t)((void *)(STACK_BASE)))
+#endif /* NRF_STACK_GUARD_ENABLED */
+
+/**@brief Initialize Stack Guard Page */
+ret_code_t nrf_stack_guard_init(void);
+
+#if NRF_STACK_GUARD_ENABLED
+#define NRF_STACK_GUARD_INIT() nrf_stack_guard_init()
+#else
+#define NRF_STACK_GUARD_INIT() NRF_SUCCESS
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__NRF_STACK_GUARD_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c
new file mode 100644
index 0000000..d61497b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c
@@ -0,0 +1,543 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(TASK_MANAGER)
+#include "nrf_mpu.h"
+#include "nrf_atomic.h"
+#include "app_util_platform.h"
+#include "task_manager.h"
+
+#if TASK_MANAGER_CLI_CMDS
+#include "nrf_cli.h"
+#endif
+
+#define NRF_LOG_MODULE_NAME task_manager
+
+#if TASK_MANAGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL TASK_MANAGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR TASK_MANAGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR TASK_MANAGER_CONFIG_DEBUG_COLOR
+#endif
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+#define STACK_GUARD_SIZE (1 << (TASK_MANAGER_CONFIG_STACK_GUARD + 1))
+STATIC_ASSERT((TASK_MANAGER_CONFIG_STACK_SIZE % STACK_GUARD_SIZE) == 0);
+#endif
+
+STATIC_ASSERT((TASK_MANAGER_CONFIG_MAX_TASKS) > 0);
+STATIC_ASSERT((TASK_MANAGER_CONFIG_STACK_SIZE % 8) == 0);
+
+// Support older CMSIS avaiable in Keil 4
+#if (__CORTEX_M == 4)
+# ifndef CONTROL_FPCA_Pos
+# define CONTROL_FPCA_Pos 2u
+# define CONTROL_FPCA_Msk (1ul << CONTROL_FPCA_Pos)
+# endif
+
+# ifndef CONTROL_SPSEL_Pos
+# define CONTROL_SPSEL_Pos 1u
+# define CONTROL_SPSEL_Msk (1ul << CONTROL_SPSEL_Pos)
+# endif
+#endif
+
+/*lint -save -esym(526,task_switch)*/
+// Declare task switching function.
+extern void task_switch(void);
+/*lint -restore*/
+
+/**@brief Idle Task ID */
+#define IDLE_TASK_ID TASK_MANAGER_CONFIG_MAX_TASKS
+#define TASK_STACK_MAGIC_WORD 0xDEADD00E
+#define TASK_FLAG_SIGNAL_MASK 0x00FFFFFF
+#define TASK_FLAG_DESTROY 0x80000000
+
+/** @brief Total number of tasks includes user configuration and idle task. */
+#define TOTAL_NUM_OF_TASKS (TASK_MANAGER_CONFIG_MAX_TASKS + 1)
+
+/**@brief Task stack with saved task state (does not include FPU state). */
+typedef struct
+{
+ uint32_t r0;
+ 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 lr;
+ uint32_t control;
+} task_stack_t;
+
+/**@brief Task State */
+typedef struct
+{
+ void *p_stack; /**< Pointer to task stack. NULL if task does not exist. */
+ const char *p_task_name;
+ nrf_atomic_u32_t flags; /**< Task flags */
+} task_state_t;
+
+/* Allocate space for task stacks:
+ *
+ * Layout:
+ * +---------------+
+ * | Idle Task |
+ * +---------------+
+ * | Stack Guard |
+ * +---------------+
+ * | Task N |
+ * +---------------+
+ * | Stack Guard |
+ * +---------------+
+ * | ... |
+ * +---------------+
+ * | Task 0 |
+ * +---------------+
+ * | Stack Guard |
+ * +---------------+
+ */
+
+typedef struct
+{
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+ uint8_t guard[STACK_GUARD_SIZE];
+#endif
+ uint8_t stack[TASK_MANAGER_CONFIG_STACK_SIZE];
+} task_manager_stack_t;
+
+/**@brief Stack space for tasks */
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+/**@brief Handle to MPU region used as a guard */
+static nrf_mpu_region_t s_guard_region;
+__ALIGN(STACK_GUARD_SIZE)
+#else
+__ALIGN(8)
+#endif
+static task_manager_stack_t s_task_stacks[TOTAL_NUM_OF_TASKS];
+
+/**@brief Task States
+ * Addtional state reserved for idle task which is mandatory.
+ * */
+static task_state_t s_task_state[TOTAL_NUM_OF_TASKS];
+
+/**@brief Mask indicating which tasks are runnable */
+static nrf_atomic_u32_t s_runnable_tasks_mask;
+
+/**@brief ID of currently executed task */
+static task_id_t s_current_task_id;
+
+/**@brief Guard page attributes: Normal memory, WBWA/WBWA, RO/RO, XN */
+#define TASK_GUARD_ATTRIBUTES ((0x05 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_B_Pos) | \
+ (0x07 << MPU_RASR_AP_Pos) | (1 << MPU_RASR_XN_Pos))
+
+
+/**@brief Macro for getting pointer to bottom of stack for given task id */
+#define BOTTOM_OF_TASK_STACK(_task_id) ((void *)(&s_task_stacks[(_task_id)].stack[0]))
+
+/**@brief Macro for getting pointer to top of stack for given task id */
+#define TOP_OF_TASK_STACK(_task_id) ((void *)(&s_task_stacks[(_task_id)].stack[TASK_MANAGER_CONFIG_STACK_SIZE]))
+
+/**@brief Macro for getting pointer to base of stack guard for given task id */
+#define TASK_STACK_GUARD_BASE(_task_id) ((void *)(&s_task_stacks[(_task_id)].guard[0]))
+
+#define TASK_ID_TO_MASK(_task_id) (0x80000000 >> (_task_id))
+
+/**@brief Puts task in RUNNABLE state */
+#define TASK_STATE_RUNNABLE(_task_id) \
+ (void)nrf_atomic_u32_or(&s_runnable_tasks_mask, TASK_ID_TO_MASK(_task_id))
+
+/**@brief Puts task in SUSPENDED state */
+#define TASK_STATE_SUSPENDED(_task_id) \
+ (void)nrf_atomic_u32_and(&s_runnable_tasks_mask, ~TASK_ID_TO_MASK(_task_id));
+
+static void task_stack_poison(task_id_t task_id)
+{
+#if TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+ unsigned int i = TASK_MANAGER_CONFIG_STACK_SIZE / sizeof(uint32_t);
+ uint32_t *p_stack_top = TOP_OF_TASK_STACK(task_id);
+
+ while (i--)
+ {
+ *(--p_stack_top) = TASK_STACK_MAGIC_WORD;
+ }
+#endif
+}
+
+static void task_stack_protect(task_id_t task_id)
+{
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+ APP_ERROR_CHECK(nrf_mpu_region_create(&s_guard_region,
+ TASK_STACK_GUARD_BASE(task_id),
+ STACK_GUARD_SIZE,
+ TASK_GUARD_ATTRIBUTES));
+#endif
+}
+
+PRAGMA_OPTIMIZATION_FORCE_START
+void task_manager_start(task_main_t idle_task, void *p_idle_task_context)
+{
+ unsigned long control;
+
+ // Idle task must be specified.
+ ASSERT(idle_task != NULL);
+
+ // Make sure that we are in privledged thread level using MSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) == 0);
+
+ // Prepare task state structure.
+ s_current_task_id = IDLE_TASK_ID;
+ s_task_state[s_current_task_id].p_task_name = "Idle Task";
+
+ // Prepare stack instrumentation and protection.
+ task_stack_poison(s_current_task_id);
+ task_stack_protect(s_current_task_id);
+
+ NRF_LOG_INFO("Task %u created (name: '%s', stack: 0x%08X-0x%08X).",
+ s_current_task_id,
+ s_task_state[s_current_task_id].p_task_name,
+ (uint32_t)BOTTOM_OF_TASK_STACK(s_current_task_id),
+ (uint32_t)TOP_OF_TASK_STACK(s_current_task_id) - 1);
+
+ // Prepare context for idle task. This must be done with all interrupts disabled.
+ __disable_irq();
+
+ // Set process and exception stacks.
+ __set_PSP((uint32_t)(TOP_OF_TASK_STACK(s_current_task_id)));
+ __set_MSP((uint32_t)(STACK_TOP));
+
+ // Update CONTROL register.
+ control = __get_CONTROL();
+ control &= CONTROL_FPCA_Msk; // Clear FPCA since FPU state does not need to be preserved.
+ control |= CONTROL_SPSEL_Msk; // Use MSP only for excpetions, leaving PSP for tasks.
+ __set_CONTROL(control);
+
+ // Context is ready. Enable interrupts.
+ __enable_irq();
+
+ // Perform task switch to run non-idle tasks as soon as possible.
+ task_switch();
+
+ // Jump to idle task.
+ idle_task(p_idle_task_context);
+
+ // This should be never reached.
+ APP_ERROR_CHECK_BOOL(false);
+}
+PRAGMA_OPTIMIZATION_FORCE_END
+
+task_id_t task_create(task_main_t task, char const * p_task_name, void *p_context)
+{
+ task_state_t *p_state = NULL;
+ task_stack_t *p_stack;
+ task_id_t task_id;
+
+ // Check arguments.
+ if (task == NULL)
+ {
+ return TASK_ID_INVALID;
+ }
+
+ // Find free task state structure.
+ CRITICAL_REGION_ENTER();
+ for (task_id = 0; task_id < TASK_MANAGER_CONFIG_MAX_TASKS; task_id++)
+ {
+ if (s_task_state[task_id].p_stack == NULL)
+ {
+ p_state = &s_task_state[task_id];
+ p_state->p_stack = TOP_OF_TASK_STACK(task_id);
+ break;
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ // Return invalid Task ID if new task cannot be created.
+ if (p_state == NULL)
+ {
+ return TASK_ID_INVALID;
+ }
+
+ // Prepare initial stack for the task.
+ task_stack_poison(task_id);
+
+ p_state->p_stack = (uint8_t *)(p_state->p_stack) - sizeof(*p_stack);
+ p_state->p_task_name = (char *)p_task_name;
+ p_state->flags = 0;
+
+ p_stack = p_state->p_stack;
+
+ p_stack->control = CONTROL_SPSEL_Msk;
+ p_stack->lr = (uint32_t)(task); // Start from this function.
+ p_stack->r0 = (uint32_t)(p_context); // Pass p_context as first argument.
+
+ // Mark task as ready to run.
+ TASK_STATE_RUNNABLE(task_id);
+
+ NRF_LOG_INFO("Task %u created (name: '%s', stack: 0x%08X-0x%08X).",
+ task_id,
+ p_task_name,
+ (uint32_t)BOTTOM_OF_TASK_STACK(task_id),
+ (uint32_t)TOP_OF_TASK_STACK(task_id) - 1);
+
+ return task_id;
+}
+
+/**@brief Task scheduler.
+ *
+ * @param[in] Pointer to task stack with saved task state.
+ * @return Pointer to new task stack with saved task state.
+ */
+void *task_schedule(void *p_stack)
+{
+ uint32_t runnable_tasks_mask;
+
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+ // Destroy stack guard allocated for current task.
+ APP_ERROR_CHECK(nrf_mpu_region_destroy(s_guard_region));
+#endif
+
+ // Save current task state if task if switching from valid task.
+ if ((s_task_state[s_current_task_id].flags & TASK_FLAG_DESTROY) == 0)
+ {
+ s_task_state[s_current_task_id].p_stack = p_stack;
+ }
+ else
+ {
+ TASK_STATE_SUSPENDED(s_current_task_id);
+ s_task_state[s_current_task_id].p_stack = NULL;
+
+ NRF_LOG_INFO("Task %u terminated (name: '%s').",
+ s_current_task_id,
+ s_task_state[s_current_task_id].p_task_name);
+ }
+
+ // Atomically fetch list of runnable tasks.
+ runnable_tasks_mask = s_runnable_tasks_mask;
+
+ // Check if there are any tasks to execute.
+ if (runnable_tasks_mask != 0)
+ {
+ // Check if we could continue this round.
+ if ((runnable_tasks_mask << (s_current_task_id + 1)) != 0)
+ {
+ // There are tasks to execute in this round. Select next runnable task:
+ s_current_task_id += 1 + __CLZ((runnable_tasks_mask << (s_current_task_id + 1)));
+ }
+ else
+ {
+ // No more tasks in this round. Select first avaiable task:
+ s_current_task_id = __CLZ(runnable_tasks_mask);
+ }
+ }
+ else
+ {
+ // Fall back to idle task if other tasks cannot be run.
+ s_current_task_id = IDLE_TASK_ID;
+ }
+
+ task_stack_protect(s_current_task_id);
+
+ // Switch to new task.
+ return s_task_state[s_current_task_id].p_stack;
+}
+
+void task_yield(void)
+{
+ // Make sure that we are in privledged thread level using PSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) != 0);
+
+ // Perform task switch.
+ task_switch();
+}
+
+uint32_t task_events_wait(uint32_t evt_mask)
+{
+ uint32_t current_events;
+
+ ASSERT((evt_mask & ~TASK_FLAG_SIGNAL_MASK) == 0);
+
+ for (;;)
+ {
+ current_events = s_task_state[s_current_task_id].flags & evt_mask;
+ if (current_events != 0)
+ {
+ (void)nrf_atomic_u32_and(&s_task_state[s_current_task_id].flags, ~current_events);
+ break;
+ }
+
+ TASK_STATE_SUSPENDED(s_current_task_id);
+ task_yield();
+ }
+
+ return current_events;
+}
+
+void task_events_set(task_id_t task_id, uint32_t evt_mask)
+{
+ ASSERT((task_id != TASK_ID_INVALID) && (task_id < TASK_MANAGER_CONFIG_MAX_TASKS));
+ ASSERT((evt_mask & ~TASK_FLAG_SIGNAL_MASK) == 0);
+ ASSERT(s_task_state[task_id].p_stack != NULL);
+
+ (void)nrf_atomic_u32_or(&s_task_state[task_id].flags, evt_mask);
+ TASK_STATE_RUNNABLE(task_id);
+}
+
+void task_exit(void)
+{
+ // Make sure that we are in privledged thread level using PSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) != 0);
+
+ s_task_state[s_current_task_id].flags = TASK_FLAG_DESTROY;
+ task_switch();
+}
+
+task_id_t task_id_get(void)
+{
+ // Make sure that we are in privledged thread level using PSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) != 0);
+
+ return s_current_task_id;
+}
+
+uint32_t task_stack_max_usage_get(task_id_t task_id)
+{
+#if TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+ unsigned int stack_usage;
+ uint32_t *p_stack, *p_stack_top;
+
+ ASSERT((task_id != TASK_ID_INVALID) || (task_id < TASK_MANAGER_CONFIG_MAX_TASKS));
+ ASSERT(s_task_state[task_id].p_stack != NULL);
+
+ p_stack_top = TOP_OF_TASK_STACK(task_id);
+ p_stack = BOTTOM_OF_TASK_STACK(task_id);
+ stack_usage = TASK_MANAGER_CONFIG_STACK_SIZE;
+
+ while (p_stack < p_stack_top)
+ {
+ if (*(p_stack++) != TASK_STACK_MAGIC_WORD)
+ {
+ break;
+ }
+
+ stack_usage -= sizeof(*p_stack);
+ }
+
+ return stack_usage;
+#else
+ return 0;
+#endif
+}
+
+#if TASK_MANAGER_CLI_CMDS
+static void task_mnanager_info(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ task_id_t task_id;
+
+ for (task_id = 0; task_id < TOTAL_NUM_OF_TASKS; task_id++)
+ {
+ const char *p_task_name = NULL;
+
+ CRITICAL_REGION_ENTER();
+ if (s_task_state[task_id].p_stack != NULL)
+ {
+ p_task_name = (s_task_state[task_id].p_task_name) ? s_task_state[task_id].p_task_name
+ : "<NULL>";
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (p_task_name)
+ {
+ uint32_t stack_usage = task_stack_max_usage_get(task_id);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Task %u:\r\n", task_id);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tName:\t'%s'\r\n", p_task_name);
+
+ if (stack_usage)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tStack:\t0x%08X-0x%08X used in %u%% (%u out of %u bytes)\r\n",
+ (uint32_t)BOTTOM_OF_TASK_STACK(task_id),
+ (uint32_t)TOP_OF_TASK_STACK(task_id) - 1,
+ 100 * stack_usage / TASK_MANAGER_CONFIG_STACK_SIZE,
+ stack_usage,
+ TASK_MANAGER_CONFIG_STACK_SIZE);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tStack:\t0x%08X-0x%08X\r\n",
+ (uint32_t)BOTTOM_OF_TASK_STACK(task_id),
+ (uint32_t)TOP_OF_TASK_STACK(task_id) - 1);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tState:\t%s\r\n",
+ (s_current_task_id == task_id) ? "Running" :
+ (s_runnable_tasks_mask & TASK_ID_TO_MASK(task_id)) ? "Runnable" : "Suspended");
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tFlags:\t0x%08X\r\n\r\n",
+ s_task_state[task_id].flags);
+
+ }
+ }
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_task_mngr)
+{
+ NRF_CLI_CMD(info, NULL, "tasks info", task_mnanager_info),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(task_manager, &m_sub_task_mngr, "commands for task manager", NULL);
+#endif //TASK_MANAGER_CLI_CMDS
+#else //TASK_MANAGER_ENABLED
+void *task_schedule(void *p_stack)
+{
+ return (void *)0;
+}
+#endif //TASK_MANAGER_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h
new file mode 100644
index 0000000..54c3930
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __TASK_MANAGER_H__
+#define __TASK_MANAGER_H__
+
+
+/**
+* @defgroup task_manager Task manager (Cooperative Scheduler)
+* @{
+* @ingroup app_common
+* @brief Functions for managing tasks
+*/
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Main function of the task. */
+typedef void (* task_main_t)(void * p_context);
+
+/**@brief Task ID */
+typedef uint8_t task_id_t;
+
+/**@brief Invalid task ID */
+#define TASK_ID_INVALID ((task_id_t)(-1))
+
+/**@brief Start task manager.
+ *
+ * @details This function starts the task manager and configures given function as idle task.
+ * This function never returns.
+ *
+ * @param[in] idle_task Main function of the task scheduled when no other tasks could be run.
+ * @param[in] p_idle_task_context Context passed to idle task.
+ */
+void task_manager_start(task_main_t idle_task, void * p_idle_task_context);
+
+/**@brief Create new task.
+ *
+ * @param[in] task Function which become main procedure of new task.
+ * @param[in] p_task_name Task name.
+ * @param[in] p_context Context passed to task procedure.
+ *
+ * @return ID of the task on success, otherwise TASK_ID_INVALID.
+ */
+task_id_t task_create(task_main_t task, char const * p_task_name, void * p_context);
+
+/**@brief Yield CPU to other tasks.
+ */
+void task_yield(void);
+
+/**@brief Complete current task.
+ *
+ * Task stack returns to the pool of available stacks.
+ */
+void task_exit(void);
+
+/**@brief Wait for events. Set events are cleared after this function returns.
+ *
+ * @param[in] evt_mask Mask of events to wait
+ *
+ * @return Mask with set events (can be a subset of evt_mask).
+ */
+uint32_t task_events_wait(uint32_t evt_mask);
+
+/**@brief Set events for given task.
+ *
+ * @param[in] task_id Id of the task which shall receive events.
+ * @param[in] evt_mask Events for the task.
+ *
+ */
+void task_events_set(task_id_t task_id, uint32_t evt_mask);
+
+/**@brief Returns maximum depth of task stack.
+ *
+ * @param[in] task_id Id of the task (use @ref TASK_ID_INVALID for current task).
+ * @return Number of bytes ever used on task stack.
+ */
+uint32_t task_stack_max_usage_get(task_id_t task_id);
+
+/**@brief Returns ID of currently running task.
+ *
+ * @return ID of active task.
+ */
+task_id_t task_id_get(void);
+
+/**@brief Set events for given task.
+ *
+ * @param[in] task_id Id of the task which name will be returned.
+ * @return Task name
+ *
+ */
+char const * task_name_get(task_id_t task_id);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TASK_MANAGER_H__ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S
new file mode 100644
index 0000000..393e878
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ .syntax unified
+ .arch armv7-m
+
+ .text
+ .thumb
+ .thumb_func
+ .align 1
+ .global task_switch
+ .type task_switch, %function
+
+task_switch:
+ .fnstart
+ MRS R0, CONTROL /* Fetch CONTROL register to R0 */
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) /* Check FPCA flag. */
+ ITTT NE
+ VMRSNE R1, FPSCR /* If FPCA set, fetch FPSCR. */
+ STMDBNE SP!, {R0, R1} /* If FPCA set, save FPSCR (also pad stack to 8-byte alignment) */
+ VSTMDBNE SP!, {S0-S31} /* If FPCA set, save FPU registers. */
+#endif
+
+ STMDB SP!, {R0} /* Save CONTROL register. */
+ AND R0, R0, #~(1 << 2) /* Clear FPCA bit. */
+ MSR CONTROL, R0 /* Update CONTROL register. */
+
+ STMDB SP!, {R0, R4-R12, LR} /* Save CPU registers. Reserve space for R0, needed to pass argument to new task. */
+
+ MOV R0, SP /* Call task scheduler with current stack pointer as argument. */
+ LDR R1, =task_schedule
+ BLX R1
+
+ MOV SP, R0 /* Switch to new stack, returned by task scheduler. */
+
+ LDMIA SP!, {R3, R4-R12, LR} /* Restore CPU registers. Argument to new task is in R3. */
+ LDMIA SP!, {R0} /* Restore CONTROL register. */
+ MSR CONTROL, R0 /* Update CONTROL register. */
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) /* Check FPCA flag. */
+ ITTT NE
+ VLDMIANE SP!, {S0-S31} /* If FPCA set, restore FPU registers. */
+ LDMIANE SP!, {R0, R1} /* If FPCA set, restore FPSCR (also remove padding). */
+ VMSRNE FPSCR, R1 /* If FPCA set, update FPSCR */
+#endif
+
+ MOV R0, R3 /* Place optional task argument in R0. */
+ BX LR /* Return to new task. */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s
new file mode 100644
index 0000000..8205d73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s
@@ -0,0 +1,83 @@
+; Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+; are permitted provided that the following conditions are met:
+;
+; 1. Redistributions of source code must retain the above copyright notice, this
+; list of conditions and the following disclaimer.
+;
+; 2. Redistributions in binary form, except as embedded into a Nordic
+; Semiconductor ASA integrated circuit in a product or a software update for
+; such product, must reproduce the above copyright notice, this list of
+; conditions and the following disclaimer in the documentation and/or other
+; materials provided with the distribution.
+;
+; 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+; contributors may be used to endorse or promote products derived from this
+; software without specific prior written permission.
+;
+; 4. This software, with or without modification, must only be used with a
+; Nordic Semiconductor ASA integrated circuit.
+;
+; 5. Any software provided in binary form under this license must not be reverse
+; engineered, decompiled, modified and/or disassembled.
+;
+; THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+; OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+; OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+ SECTION .text:CODE:REORDER:NOROOT(2)
+ THUMB
+
+ PUBLIC task_switch
+ EXTERN task_schedule
+
+task_switch
+ MRS R0, CONTROL ; Fetch CONTROL register to R0
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VMRSNE R1, FPSCR ; If FPCA set, fetch FPSCR.
+ STMDBNE SP!, {R0, R1} ; If FPCA set, save FPSCR (also pad stack to 8-byte alignment)
+ VSTMDBNE SP!, {S0-S31} ; If FPCA set, save FPU registers.
+#endif
+
+ STMDB SP!, {R0} ; Save CONTROL register.
+ AND R0, R0, #~(1 << 2) ; Clear FPCA bit.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+ STMDB SP!, {R0, R4-R12, LR} ; Save CPU registers. Reserve space for R0, needed to pass argument to new task.
+
+ MOV R0, SP ; Call task scheduler with current stack pointer as argument.
+ LDR R1, =task_schedule ;
+ BLX R1 ;
+
+ MOV SP, R0 ; Switch to new stack, returned by task scheduler.
+
+ LDMIA SP!, {R3, R4-R12, LR} ; Restore CPU registers. Argument to new task is in R3.
+ LDMIA SP!, {R0} ; Restore CONTROL register.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VLDMIANE SP!, {S0-S31} ; If FPCA set, restore FPU registers.
+ LDMIANE SP!, {R0, R1} ; If FPCA set, restore FPSCR (also remove padding).
+ VMSRNE FPSCR, R1 ; If FPCA set, update FPSCR
+#endif
+
+ MOV R0, R3 ; Place optional task argument in R0.
+ BX LR ; Return to new task.
+
+ END
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s
new file mode 100644
index 0000000..874b84d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s
@@ -0,0 +1,85 @@
+; Copyright (c) 2017 - 2017, Nordic Semiconductor ASA
+;
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without modification,
+; are permitted provided that the following conditions are met:
+;
+; 1. Redistributions of source code must retain the above copyright notice, this
+; list of conditions and the following disclaimer.
+;
+; 2. Redistributions in binary form, except as embedded into a Nordic
+; Semiconductor ASA integrated circuit in a product or a software update for
+; such product, must reproduce the above copyright notice, this list of
+; conditions and the following disclaimer in the documentation and/or other
+; materials provided with the distribution.
+;
+; 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+; contributors may be used to endorse or promote products derived from this
+; software without specific prior written permission.
+;
+; 4. This software, with or without modification, must only be used with a
+; Nordic Semiconductor ASA integrated circuit.
+;
+; 5. Any software provided in binary form under this license must not be reverse
+; engineered, decompiled, modified and/or disassembled.
+;
+; THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+; OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+; OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+ PRESERVE8
+ THUMB
+ AREA |.text|, CODE, READONLY
+
+task_switch PROC
+ EXPORT task_switch
+ IMPORT task_schedule
+
+ MRS R0, CONTROL ; Fetch CONTROL register to R0
+
+ IF :DEF: FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VMRSNE R1, FPSCR ; If FPCA set, fetch FPSCR.
+ STMDBNE SP!, {R0, R1} ; If FPCA set, save FPSCR (also pad stack to 8-byte alignment)
+ VSTMDBNE SP!, {S0-S31} ; If FPCA set, save FPU registers.
+ ENDIF
+
+ STMDB SP!, {R0} ; Save CONTROL register.
+ AND R0, R0, #~(1 << 2) ; Clear FPCA bit.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+ STMDB SP!, {R0, R4-R12, LR} ; Save CPU registers. Reserve space for R0, needed to pass argument to new task.
+
+ MOV R0, SP ; Call task scheduler with current stack pointer as argument.
+ LDR R1, =task_schedule ;
+ BLX R1 ;
+
+ MOV SP, R0 ; Switch to new stack, returned by task scheduler.
+
+ LDMIA SP!, {R3, R4-R12, LR} ; Restore CPU registers. Argument to new task is in R3.
+ LDMIA SP!, {R0} ; Restore CONTROL register.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+ IF :DEF: FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VLDMIANE SP!, {S0-S31} ; If FPCA set, restore FPU registers.
+ LDMIANE SP!, {R0, R1} ; If FPCA set, restore FPSCR (also remove padding).
+ VMSRNE FPSCR, R1 ; If FPCA set, update FPSCR
+ ENDIF
+
+ MOV R0, R3 ; Place optional task argument in R0.
+ BX LR ; Return to new task.
+
+ ENDP
+ END
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c
new file mode 100644
index 0000000..99ddc66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c
@@ -0,0 +1,2164 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(FDS)
+#include "fds.h"
+#include "fds_internal_defs.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nrf_error.h"
+#include "nrf_atomic.h"
+#include "nrf_atfifo.h"
+
+#include "nrf_fstorage.h"
+#if (FDS_BACKEND == NRF_FSTORAGE_SD)
+#include "nrf_fstorage_sd.h"
+#elif (FDS_BACKEND == NRF_FSTORAGE_NVMC)
+#include "nrf_fstorage_nvmc.h"
+#else
+#error Invalid FDS backend.
+#endif
+
+#if (FDS_CRC_CHECK_ON_READ)
+#include "crc16.h"
+#endif
+
+
+static void fs_event_handler(nrf_fstorage_evt_t * evt);
+
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_fs) =
+{
+ // The flash area boundaries are set in fds_init().
+ .evt_handler = fs_event_handler,
+};
+
+// Internal status flags.
+static struct
+{
+ bool volatile initialized;
+ nrf_atomic_flag_t initializing;
+} m_flags;
+
+// The number of queued operations.
+// Incremented by queue_start() and decremented by queue_has_next().
+static nrf_atomic_u32_t m_queued_op_cnt;
+
+// The number of registered users and their callback functions.
+static nrf_atomic_u32_t m_users;
+static fds_cb_t m_cb_table[FDS_MAX_USERS];
+
+// The latest (largest) record ID written so far.
+static nrf_atomic_u32_t m_latest_rec_id;
+
+// Queue of fds operations.
+NRF_ATFIFO_DEF(m_queue, fds_op_t, FDS_OP_QUEUE_SIZE);
+
+// Structures used to hold informations about virtual pages.
+static fds_page_t m_pages[FDS_DATA_PAGES];
+static fds_swap_page_t m_swap_page;
+
+// Garbage collection data.
+static fds_gc_data_t m_gc;
+
+
+static void event_send(fds_evt_t const * const p_evt)
+{
+ for (uint32_t user = 0; user < FDS_MAX_USERS; user++)
+ {
+ if (m_cb_table[user] != NULL)
+ {
+ m_cb_table[user](p_evt);
+ }
+ }
+}
+
+
+static void event_prepare(fds_op_t const * const p_op, fds_evt_t * const p_evt)
+{
+ switch (p_op->op_code)
+ {
+ case FDS_OP_INIT:
+ p_evt->id = FDS_EVT_INIT;
+ break;
+
+ case FDS_OP_WRITE:
+ p_evt->id = FDS_EVT_WRITE;
+ p_evt->write.file_id = p_op->write.header.file_id;
+ p_evt->write.record_key = p_op->write.header.record_key;
+ p_evt->write.record_id = p_op->write.header.record_id;
+ p_evt->write.is_record_updated = 0;
+ break;
+
+ case FDS_OP_UPDATE:
+ p_evt->id = FDS_EVT_UPDATE;
+ p_evt->write.file_id = p_op->write.header.file_id;
+ p_evt->write.record_key = p_op->write.header.record_key;
+ p_evt->write.record_id = p_op->write.header.record_id;
+ p_evt->write.is_record_updated = (p_op->write.step == FDS_OP_WRITE_DONE);
+ break;
+
+ case FDS_OP_DEL_RECORD:
+ p_evt->id = FDS_EVT_DEL_RECORD;
+ p_evt->del.file_id = p_op->del.file_id;
+ p_evt->del.record_key = p_op->del.record_key;
+ p_evt->del.record_id = p_op->del.record_to_delete;
+ break;
+
+ case FDS_OP_DEL_FILE:
+ p_evt->id = FDS_EVT_DEL_FILE;
+ p_evt->del.file_id = p_op->del.file_id;
+ p_evt->del.record_key = FDS_RECORD_KEY_DIRTY;
+ p_evt->del.record_id = 0;
+ break;
+
+ case FDS_OP_GC:
+ p_evt->id = FDS_EVT_GC;
+ break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+}
+
+
+static bool header_has_next(fds_header_t const * p_hdr, uint32_t const * p_page_end)
+{
+ uint32_t const * const p_hdr32 = (uint32_t*)p_hdr;
+ return ( ( p_hdr32 < p_page_end)
+ && (*p_hdr32 != FDS_ERASED_WORD)); // Check last to be on the safe side (dereference)
+}
+
+
+// Jump to the next header.
+static fds_header_t const * header_jump(fds_header_t const * const p_hdr)
+{
+ return (fds_header_t*)((uint32_t*)p_hdr + FDS_HEADER_SIZE + p_hdr->length_words);
+}
+
+
+static fds_header_status_t header_check(fds_header_t const * p_hdr, uint32_t const * p_page_end)
+{
+ if (((uint32_t*)header_jump(p_hdr) > p_page_end))
+ {
+ // The length field would jump across the page boundary.
+ // FDS won't allow writing such a header, therefore it has been corrupted.
+ return FDS_HEADER_CORRUPT;
+ }
+
+ if ( (p_hdr->file_id == FDS_FILE_ID_INVALID)
+ || (p_hdr->record_key == FDS_RECORD_KEY_DIRTY))
+ {
+ return FDS_HEADER_DIRTY;
+ }
+
+ return FDS_HEADER_VALID;
+}
+
+
+static bool address_is_valid(uint32_t const * const p_addr)
+{
+ return ((p_addr != NULL) &&
+ (p_addr >= (uint32_t*)m_fs.start_addr) &&
+ (p_addr <= (uint32_t*)m_fs.end_addr) &&
+ (is_word_aligned(p_addr)));
+}
+
+
+// Reads a page tag, and determines if the page is used to store data or as swap.
+static fds_page_type_t page_identify(uint32_t const * const p_page_addr)
+{
+ if ( (p_page_addr == NULL) // Should never happen.
+ || (p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_PAGE_TAG_MAGIC))
+ {
+ return FDS_PAGE_UNDEFINED;
+ }
+
+ switch (p_page_addr[FDS_PAGE_TAG_WORD_1])
+ {
+ case FDS_PAGE_TAG_SWAP:
+ return FDS_PAGE_SWAP;
+
+ case FDS_PAGE_TAG_DATA:
+ return FDS_PAGE_DATA;
+
+ default:
+ return FDS_PAGE_UNDEFINED;
+ }
+}
+
+
+static bool page_is_erased(uint32_t const * const p_page_addr)
+{
+ for (uint32_t i = 0; i < FDS_PAGE_SIZE; i++)
+ {
+ if (*(p_page_addr + i) != FDS_ERASED_WORD)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+// NOTE: Must be called from within a critical section.
+static bool page_has_space(uint16_t page, uint16_t length_words)
+{
+ length_words += m_pages[page].write_offset;
+ length_words += m_pages[page].words_reserved;
+ return (length_words < FDS_PAGE_SIZE);
+}
+
+
+// Given a pointer to a record, find the index of the page on which it is stored.
+// Returns FDS_SUCCESS if the page is found, FDS_ERR_NOT_FOUND otherwise.
+static ret_code_t page_from_record(uint16_t * const p_page, uint32_t const * const p_rec)
+{
+ ret_code_t ret = FDS_ERR_NOT_FOUND;
+
+ CRITICAL_SECTION_ENTER();
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ if ((p_rec > m_pages[i].p_addr) &&
+ (p_rec < m_pages[i].p_addr + FDS_PAGE_SIZE))
+ {
+ ret = FDS_SUCCESS;
+ *p_page = i;
+ break;
+ }
+ }
+ CRITICAL_SECTION_EXIT();
+
+ return ret;
+}
+
+
+// Scan a page to determine how many words have been written to it.
+// This information is used to set the page write offset during initialization.
+// Additionally, this function updates the latest record ID as it proceeds.
+// If an invalid record header is found, the can_gc argument is set to true.
+static void page_scan(uint32_t const * p_addr,
+ uint16_t * const words_written,
+ bool * const can_gc)
+{
+ uint32_t const * const p_page_end = p_addr + FDS_PAGE_SIZE;
+
+ p_addr += FDS_PAGE_TAG_SIZE;
+ *words_written = FDS_PAGE_TAG_SIZE;
+
+ fds_header_t const * p_header = (fds_header_t*)p_addr;
+
+ while (header_has_next(p_header, p_page_end))
+ {
+ fds_header_status_t hdr = header_check(p_header, p_page_end);
+
+ if (hdr == FDS_HEADER_VALID)
+ {
+ // Update the latest (largest) record ID.
+ if (p_header->record_id > m_latest_rec_id)
+ {
+ m_latest_rec_id = p_header->record_id;
+ }
+ }
+ else
+ {
+ if (can_gc != NULL)
+ {
+ *can_gc = true;
+ }
+
+ if (hdr == FDS_HEADER_CORRUPT)
+ {
+ // It could happen that a record has a corrupt header which would set a
+ // wrong offset for this page. In such cases, update this value to its maximum,
+ // to ensure that no new records will be written to this page and to enable
+ // correct statistics reporting by fds_stat().
+ *words_written = FDS_PAGE_SIZE;
+
+ // We can't continue to scan this page.
+ return;
+ }
+ }
+
+ *words_written += (FDS_HEADER_SIZE + p_header->length_words);
+ p_header = header_jump(p_header);
+ }
+}
+
+
+static void page_offsets_update(fds_page_t * const p_page, fds_op_t const * p_op)
+{
+ // If the first part of the header has been written correctly, update the offset as normal.
+ // Even if the record has not been written completely, fds is still able to continue normal
+ // operation. Incomplete records will be deleted the next time garbage collection is run.
+ // If we failed at the very beginning of the write operation, restore the offset
+ // to the previous value so that no holes will be left in the flash.
+ if (p_op->write.step > FDS_OP_WRITE_RECORD_ID)
+ {
+ p_page->write_offset += (FDS_HEADER_SIZE + p_op->write.header.length_words);
+ }
+
+ p_page->words_reserved -= (FDS_HEADER_SIZE + p_op->write.header.length_words);
+}
+
+
+// Tags a page as swap, i.e., reserved for GC.
+static ret_code_t page_tag_write_swap(void)
+{
+ // The tag needs to be statically allocated since it is not buffered by fstorage.
+ static uint32_t const page_tag_swap[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_SWAP};
+ return nrf_fstorage_write(&m_fs, (uint32_t)m_swap_page.p_addr, page_tag_swap, FDS_PAGE_TAG_SIZE * sizeof(uint32_t), NULL);
+}
+
+
+// Tags a page as data, i.e, ready for storage.
+static ret_code_t page_tag_write_data(uint32_t const * const p_page_addr)
+{
+ // The tag needs to be statically allocated since it is not buffered by fstorage.
+ static uint32_t const page_tag_data[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_DATA};
+ return nrf_fstorage_write(&m_fs, (uint32_t)p_page_addr, page_tag_data, FDS_PAGE_TAG_SIZE * sizeof(uint32_t), NULL);
+}
+
+
+// Reserve space on a page.
+// NOTE: this function takes into the account the space required for the record header.
+static ret_code_t write_space_reserve(uint16_t length_words, uint16_t * p_page)
+{
+ bool space_reserved = false;
+ uint16_t const total_len_words = length_words + FDS_HEADER_SIZE;
+
+ if (total_len_words >= FDS_PAGE_SIZE - FDS_PAGE_TAG_SIZE)
+ {
+ return FDS_ERR_RECORD_TOO_LARGE;
+ }
+
+ CRITICAL_SECTION_ENTER();
+ for (uint16_t page = 0; page < FDS_DATA_PAGES; page++)
+ {
+ if ((m_pages[page].page_type == FDS_PAGE_DATA) &&
+ (page_has_space(page, total_len_words)))
+ {
+ space_reserved = true;
+ *p_page = page;
+
+ m_pages[page].words_reserved += total_len_words;
+ break;
+ }
+ }
+ CRITICAL_SECTION_EXIT();
+
+ return (space_reserved) ? FDS_SUCCESS : FDS_ERR_NO_SPACE_IN_FLASH;
+}
+
+
+// Undo a write_space_reserve() call.
+// NOTE: Must be called within a critical section.
+static void write_space_free(uint16_t length_words, uint16_t page)
+{
+ m_pages[page].words_reserved -= (length_words + FDS_HEADER_SIZE);
+}
+
+
+static uint32_t record_id_new(void)
+{
+ return nrf_atomic_u32_add(&m_latest_rec_id, 1);
+}
+
+
+// Given a page and a record, find the next valid record on that page.
+// If p_record is NULL, search from the beginning of the page,
+// otherwise, resume searching from p_record.
+// Return true if a record is found, false otherwise.
+// If no record is found, p_record is unchanged.
+static bool record_find_next(uint16_t page, uint32_t const ** p_record)
+{
+ uint32_t const * p_page_end = (m_pages[page].p_addr + FDS_PAGE_SIZE);
+
+ // If this is the first call on this page, start searching from its beginning.
+ // Otherwise, jump to the next record.
+ fds_header_t const * p_header = (fds_header_t*)(*p_record);
+
+ if (p_header != NULL)
+ {
+ p_header = header_jump(p_header);
+ }
+ else
+ {
+ p_header = (fds_header_t*)(m_pages[page].p_addr + FDS_PAGE_TAG_SIZE);
+ }
+
+ // Read records from the page until:
+ // - a valid record is found or
+ // - the last record on a page is found
+
+ while (header_has_next(p_header, p_page_end))
+ {
+ switch (header_check(p_header, p_page_end))
+ {
+ case FDS_HEADER_VALID:
+ *p_record = (uint32_t*)p_header;
+ return true;
+
+ case FDS_HEADER_DIRTY:
+ p_header = header_jump(p_header);
+ break;
+
+ case FDS_HEADER_CORRUPT:
+ // We can't reliably jump over this record.
+ // There is nothing more we can do on this page.
+ return false;
+ }
+ }
+
+ // No more valid records on this page.
+ return false;
+}
+
+
+// Find a record given its descriptor and retrive the page in which the record is stored.
+// NOTE: Do not pass NULL as an argument for p_page.
+static bool record_find_by_desc(fds_record_desc_t * const p_desc, uint16_t * const p_page)
+{
+ // If the gc_run_count field in the descriptor matches our counter, then the record has
+ // not been moved. If the address is valid, and the record ID matches, there is no need
+ // to find the record again. Only lookup the page in which the record is stored.
+
+ if ((address_is_valid(p_desc->p_record)) &&
+ (p_desc->gc_run_count == m_gc.run_count) &&
+ (p_desc->record_id == ((fds_header_t*)p_desc->p_record)->record_id))
+ {
+ return (page_from_record(p_page, p_desc->p_record) == FDS_SUCCESS);
+ }
+
+ // Otherwise, find the record in flash.
+ for (*p_page = 0; *p_page < FDS_DATA_PAGES; (*p_page)++)
+ {
+ // Set p_record to NULL to make record_find_next() search from the beginning of the page.
+ uint32_t const * p_record = NULL;
+
+ while (record_find_next(*p_page, &p_record))
+ {
+ fds_header_t const * const p_header = (fds_header_t*)p_record;
+ if (p_header->record_id == p_desc->record_id)
+ {
+ p_desc->p_record = p_record;
+ p_desc->gc_run_count = m_gc.run_count;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+// Search for a record and return its descriptor.
+// If p_file_id is NULL, only the record key will be used for matching.
+// If p_record_key is NULL, only the file ID will be used for matching.
+// If both are NULL, it will iterate through all records.
+static ret_code_t record_find(uint16_t const * p_file_id,
+ uint16_t const * p_record_key,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token)
+{
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_desc == NULL || p_token == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ // Begin (or resume) searching for a record.
+ for (; p_token->page < FDS_DATA_PAGES; p_token->page++)
+ {
+ if (m_pages[p_token->page].page_type != FDS_PAGE_DATA)
+ {
+ // It might be that the page is FDS_PAGE_UNDEFINED.
+ // Skip this page.
+ continue;
+ }
+
+ while (record_find_next(p_token->page, &p_token->p_addr))
+ {
+ fds_header_t const * p_header = (fds_header_t*)p_token->p_addr;
+
+ // A valid record was found, check its header for a match.
+ if ((p_file_id != NULL) &&
+ (p_header->file_id != *p_file_id))
+ {
+ continue;
+ }
+
+ if ((p_record_key != NULL) &&
+ (p_header->record_key != *p_record_key))
+ {
+ continue;
+ }
+
+ // Record found; update the descriptor.
+ p_desc->record_id = p_header->record_id;
+ p_desc->p_record = p_token->p_addr;
+ p_desc->gc_run_count = m_gc.run_count;
+
+ return FDS_SUCCESS;
+ }
+
+ // We have scanned an entire page. Set the address in the token to NULL
+ // so that it will be updated in the next iteration.
+ p_token->p_addr = NULL;
+ }
+
+ return FDS_ERR_NOT_FOUND;
+}
+
+
+// Retrieve statistics about dirty records on a page.
+static void records_stat(uint16_t page,
+ uint16_t * p_valid_records,
+ uint16_t * p_dirty_records,
+ uint16_t * p_freeable_words,
+ bool * p_corruption)
+{
+ fds_header_t const * p_header = (fds_header_t*)(m_pages[page].p_addr + FDS_PAGE_TAG_SIZE);
+ uint32_t const * const p_page_end = (m_pages[page].p_addr + FDS_PAGE_SIZE);
+
+ while (header_has_next(p_header, p_page_end))
+ {
+ switch (header_check(p_header, p_page_end))
+ {
+ case FDS_HEADER_DIRTY:
+ *p_dirty_records += 1;
+ *p_freeable_words += FDS_HEADER_SIZE + p_header->length_words;
+ p_header = header_jump(p_header);
+ break;
+
+ case FDS_HEADER_VALID:
+ *p_valid_records += 1;
+ p_header = header_jump(p_header);
+ break;
+
+ case FDS_HEADER_CORRUPT:
+ {
+ *p_dirty_records += 1;
+ *p_freeable_words += (p_page_end - (uint32_t*)p_header);
+ *p_corruption = true;
+ // We can't continue on this page.
+ return;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+
+
+// Get a buffer on the queue of operations.
+static fds_op_t * queue_buf_get(nrf_atfifo_item_put_t * p_iput_ctx)
+{
+ fds_op_t * const p_op = (fds_op_t*) nrf_atfifo_item_alloc(m_queue, p_iput_ctx);
+
+ memset(p_op, 0x00, sizeof(fds_op_t));
+ return p_op;
+}
+
+
+// Commit a buffer to the queue of operations.
+static void queue_buf_store(nrf_atfifo_item_put_t * p_iput_ctx)
+{
+ (void) nrf_atfifo_item_put(m_queue, p_iput_ctx);
+}
+
+
+// Load the next operation from the queue.
+static fds_op_t * queue_load(nrf_atfifo_item_get_t * p_iget_ctx)
+{
+ return (fds_op_t*) nrf_atfifo_item_get(m_queue, p_iget_ctx);
+}
+
+
+// Free the currently loaded operation.
+static void queue_free(nrf_atfifo_item_get_t * p_iget_ctx)
+{
+ // Free the current queue element.
+ (void) nrf_atfifo_item_free(m_queue, p_iget_ctx);
+}
+
+
+static bool queue_has_next(void)
+{
+ // Decrement the number of queued operations.
+ ASSERT(m_queued_op_cnt != 0);
+ return nrf_atomic_u32_sub(&m_queued_op_cnt, 1);
+}
+
+
+// This function is called during initialization to setup the page structure (m_pages) and
+// provide additional information regarding eventual further initialization steps.
+static fds_init_opts_t pages_init(void)
+{
+ uint32_t ret = NO_PAGES;
+ uint16_t page = 0;
+ uint16_t total_pages_available = FDS_VIRTUAL_PAGES;
+ bool swap_set_but_not_found = false;
+
+ for (uint16_t i = 0; i < FDS_VIRTUAL_PAGES; i++)
+ {
+ uint32_t const * const p_page_addr = (uint32_t*)m_fs.start_addr + (i * FDS_PAGE_SIZE);
+ fds_page_type_t const page_type = page_identify(p_page_addr);
+
+ switch (page_type)
+ {
+ case FDS_PAGE_UNDEFINED:
+ {
+ if (page_is_erased(p_page_addr))
+ {
+ if (m_swap_page.p_addr != NULL)
+ {
+ // If a swap page is already set, flag the page as erased (in m_pages)
+ // and try to tag it as data (in flash) later on during initialization.
+ m_pages[page].page_type = FDS_PAGE_ERASED;
+ m_pages[page].p_addr = p_page_addr;
+ m_pages[page].write_offset = FDS_PAGE_TAG_SIZE;
+
+ // This is a candidate for a potential new swap page, in case the
+ // current swap is going to be promoted to complete a GC instance.
+ m_gc.cur_page = page;
+ page++;
+ }
+ else
+ {
+ // If there is no swap page yet, use this one.
+ m_swap_page.p_addr = p_page_addr;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+ swap_set_but_not_found = true;
+ }
+
+ ret |= PAGE_ERASED;
+ }
+ else
+ {
+ // The page contains non-FDS data.
+ // Do not initialize or use this page.
+ total_pages_available--;
+ m_pages[page].p_addr = p_page_addr;
+ m_pages[page].page_type = FDS_PAGE_UNDEFINED;
+ page++;
+ }
+ } break;
+
+ case FDS_PAGE_DATA:
+ {
+ m_pages[page].page_type = FDS_PAGE_DATA;
+ m_pages[page].p_addr = p_page_addr;
+
+ // Scan the page to compute its write offset and determine whether or not the page
+ // can be garbage collected. Additionally, update the latest kwown record ID.
+ page_scan(p_page_addr, &m_pages[page].write_offset, &m_pages[page].can_gc);
+
+ ret |= PAGE_DATA;
+ page++;
+ } break;
+
+ case FDS_PAGE_SWAP:
+ {
+ if (swap_set_but_not_found)
+ {
+ m_pages[page].page_type = FDS_PAGE_ERASED;
+ m_pages[page].p_addr = m_swap_page.p_addr;
+ m_pages[page].write_offset = FDS_PAGE_TAG_SIZE;
+
+ page++;
+ }
+
+ m_swap_page.p_addr = p_page_addr;
+ // If the swap is promoted, this offset should be kept, otherwise,
+ // it should be set to FDS_PAGE_TAG_SIZE.
+ page_scan(p_page_addr, &m_swap_page.write_offset, NULL);
+
+ ret |= (m_swap_page.write_offset == FDS_PAGE_TAG_SIZE) ?
+ PAGE_SWAP_CLEAN : PAGE_SWAP_DIRTY;
+ } break;
+
+ default:
+ // Shouldn't happen.
+ break;
+ }
+ }
+
+ if (total_pages_available < 2)
+ {
+ ret &= NO_PAGES;
+ }
+
+ return (fds_init_opts_t)ret;
+}
+
+
+// Write the first part of a record header (the key and length).
+static ret_code_t record_header_write_begin(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ // Write the record ID next.
+ p_op->write.step = FDS_OP_WRITE_RECORD_ID;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_TL),
+ &p_op->write.header.record_key, FDS_HEADER_SIZE_TL * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+static ret_code_t record_header_write_id(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ // If this record has no data, write the last part of the header directly.
+ // Otherwise, write the record data next.
+ p_op->write.step = (p_op->write.p_data != NULL) ?
+ FDS_OP_WRITE_DATA : FDS_OP_WRITE_HEADER_FINALIZE;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_ID),
+ &p_op->write.header.record_id, FDS_HEADER_SIZE_ID * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+static ret_code_t record_header_write_finalize(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ // If this is a simple write operation, then this is the last step.
+ // If this is an update instead, delete the old record next.
+ p_op->write.step = (p_op->op_code == FDS_OP_UPDATE) ?
+ FDS_OP_WRITE_FLAG_DIRTY : FDS_OP_WRITE_DONE;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_IC),
+ &p_op->write.header.file_id, FDS_HEADER_SIZE_IC * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+static ret_code_t record_header_flag_dirty(uint32_t * const p_record, uint16_t page_to_gc)
+{
+ // Used to flag a record as dirty, i.e. ready for garbage collection.
+ // Must be statically allocated since it will be written to flash.
+ __ALIGN(4) static uint32_t const dirty_header = {0xFFFF0000};
+
+ // Flag the record as dirty.
+ ret_code_t ret;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)p_record,
+ &dirty_header, FDS_HEADER_SIZE_TL * sizeof(uint32_t), NULL);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return FDS_ERR_BUSY;
+ }
+
+ m_pages[page_to_gc].can_gc = true;
+
+ return FDS_SUCCESS;
+}
+
+
+static ret_code_t record_find_and_delete(fds_op_t * const p_op)
+{
+ ret_code_t ret;
+ uint16_t page;
+ fds_record_desc_t desc = {0};
+
+ desc.record_id = p_op->del.record_to_delete;
+
+ if (record_find_by_desc(&desc, &page))
+ {
+ fds_header_t const * const p_header = (fds_header_t const *)desc.p_record;
+
+ // Copy the record key and file ID, so that they can be returned in the event.
+ // In case this function is run as part of an update, there is no need to copy
+ // the file ID and record key since they are present in the header stored
+ // in the queue element.
+
+ p_op->del.file_id = p_header->file_id;
+ p_op->del.record_key = p_header->record_key;
+
+ // Flag the record as dirty.
+ ret = record_header_flag_dirty((uint32_t*)desc.p_record, page);
+ }
+ else
+ {
+ // The record never existed, or it has already been deleted.
+ ret = FDS_ERR_NOT_FOUND;
+ }
+
+ return ret;
+}
+
+
+// Finds a record within a file and flags it as dirty.
+static ret_code_t file_find_and_delete(fds_op_t * const p_op)
+{
+ ret_code_t ret;
+ fds_record_desc_t desc;
+
+ // This token must persist across calls.
+ static fds_find_token_t tok = {0};
+
+ // Pass NULL to ignore the record key.
+ ret = record_find(&p_op->del.file_id, NULL, &desc, &tok);
+
+ if (ret == FDS_SUCCESS)
+ {
+ // A record was found: flag it as dirty.
+ ret = record_header_flag_dirty((uint32_t*)desc.p_record, tok.page);
+ }
+ else // FDS_ERR_NOT_FOUND
+ {
+ // No more records were found. Zero the token, so that it can be reused.
+ memset(&tok, 0x00, sizeof(fds_find_token_t));
+ }
+
+ return ret;
+}
+
+
+// Writes record data to flash.
+static ret_code_t record_write_data(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ p_op->write.step = FDS_OP_WRITE_HEADER_FINALIZE;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_DATA),
+ p_op->write.p_data, p_op->write.header.length_words * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+#if (FDS_CRC_CHECK_ON_READ)
+static bool crc_verify_success(uint16_t crc, uint16_t len_words, uint32_t const * const p_data)
+{
+ uint16_t computed_crc;
+
+ // The CRC is computed on the entire record, except the CRC field itself.
+ // The record header is 12 bytes, out of these we have to skip bytes 6 to 8 where the
+ // CRC itself is stored. Then we compute the CRC for the rest of the record, from byte 8 of
+ // the header (where the record ID begins) to the end of the record data.
+ computed_crc = crc16_compute((uint8_t const *)p_data, 6, NULL);
+ computed_crc = crc16_compute((uint8_t const *)p_data + 8,
+ (FDS_HEADER_SIZE_ID + len_words) * sizeof(uint32_t),
+ &computed_crc);
+
+ return (computed_crc == crc);
+}
+#endif
+
+
+static void gc_init(void)
+{
+ m_gc.run_count++;
+ m_gc.cur_page = 0;
+ m_gc.resume = false;
+
+ // Setup which pages to GC. Defer checking for open records and the can_gc flag,
+ // as other operations might change those while GC is running.
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ m_gc.do_gc_page[i] = (m_pages[i].page_type == FDS_PAGE_DATA);
+ }
+}
+
+
+// Obtain the next page to be garbage collected.
+// Returns true if there are pages left to garbage collect, returns false otherwise.
+static bool gc_page_next(uint16_t * const p_next_page)
+{
+ bool ret = false;
+
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ if (m_gc.do_gc_page[i])
+ {
+ // Do not attempt to GC this page again.
+ m_gc.do_gc_page[i] = false;
+
+ // Only GC pages with no open records and with some records which have been deleted.
+ if ((m_pages[i].records_open == 0) && (m_pages[i].can_gc == true))
+ {
+ *p_next_page = i;
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+static ret_code_t gc_swap_erase(void)
+{
+ m_gc.state = GC_DISCARD_SWAP;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+
+ return nrf_fstorage_erase(&m_fs, (uint32_t)m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL);
+}
+
+
+// Erase the page being garbage collected, or erase the swap in case there are any open
+// records on the page being garbage collected.
+static ret_code_t gc_page_erase(void)
+{
+ uint32_t ret;
+ uint16_t const gc = m_gc.cur_page;
+
+ if (m_pages[gc].records_open == 0)
+ {
+ m_gc.state = GC_ERASE_PAGE;
+
+ ret = nrf_fstorage_erase(&m_fs, (uint32_t)m_pages[gc].p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL);
+ }
+ else
+ {
+ // If there are open records, stop garbage collection on this page.
+ // Discard the swap and try to garbage collect another page.
+ ret = gc_swap_erase();
+ }
+
+ return ret;
+}
+
+
+// Copy the current record to swap.
+static ret_code_t gc_record_copy(void)
+{
+ fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src;
+ uint32_t const * const p_dest = m_swap_page.p_addr + m_swap_page.write_offset;
+ uint16_t const record_len = FDS_HEADER_SIZE + p_header->length_words;
+
+ m_gc.state = GC_COPY_RECORD;
+
+ // Copy the record to swap; it is guaranteed to fit in the destination page,
+ // so there is no need to check its size. This will either succeed or timeout.
+ return nrf_fstorage_write(&m_fs, (uint32_t)p_dest, m_gc.p_record_src,
+ record_len * sizeof(uint32_t),
+ NULL);
+}
+
+
+static ret_code_t gc_record_find_next(void)
+{
+ ret_code_t ret;
+
+ // Find the next valid record to copy.
+ if (record_find_next(m_gc.cur_page, &m_gc.p_record_src))
+ {
+ ret = gc_record_copy();
+ }
+ else
+ {
+ // No more records left to copy on this page; swap pages.
+ ret = gc_page_erase();
+ }
+
+ return ret;
+}
+
+
+// Promote the swap by tagging it as a data page.
+static ret_code_t gc_swap_promote(void)
+{
+ m_gc.state = GC_PROMOTE_SWAP;
+ return page_tag_write_data(m_pages[m_gc.cur_page].p_addr);
+}
+
+
+// Tag the page just garbage collected as swap.
+static ret_code_t gc_tag_new_swap(void)
+{
+ m_gc.state = GC_TAG_NEW_SWAP;
+ m_gc.p_record_src = NULL;
+ return page_tag_write_swap();
+}
+
+
+static ret_code_t gc_next_page(void)
+{
+ if (!gc_page_next(&m_gc.cur_page))
+ {
+ // No pages left to GC; GC has terminated. Reset the state.
+ m_gc.state = GC_BEGIN;
+ m_gc.cur_page = 0;
+ m_gc.p_record_src = NULL;
+
+ return FDS_OP_COMPLETED;
+ }
+
+ return gc_record_find_next();
+}
+
+
+// Update the swap page offeset after a record has been successfully copied to it.
+static void gc_update_swap_offset(void)
+{
+ fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src;
+ uint16_t const record_len = FDS_HEADER_SIZE + p_header->length_words;
+
+ m_swap_page.write_offset += record_len;
+}
+
+
+static void gc_swap_pages(void)
+{
+ // The page being garbage collected will be the new swap page,
+ // and the current swap will be used as a data page (promoted).
+ uint32_t const * const p_addr = m_swap_page.p_addr;
+
+ m_swap_page.p_addr = m_pages[m_gc.cur_page].p_addr;
+ m_pages[m_gc.cur_page].p_addr = p_addr;
+
+ // Keep the offset for this page, but reset it for the swap.
+ m_pages[m_gc.cur_page].write_offset = m_swap_page.write_offset;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+}
+
+
+static void gc_state_advance(void)
+{
+ switch (m_gc.state)
+ {
+ case GC_BEGIN:
+ gc_init();
+ m_gc.state = GC_NEXT_PAGE;
+ break;
+
+ // A record was successfully copied.
+ case GC_COPY_RECORD:
+ gc_update_swap_offset();
+ m_gc.state = GC_FIND_NEXT_RECORD;
+ break;
+
+ // A page was successfully erased. Prepare to promote the swap.
+ case GC_ERASE_PAGE:
+ gc_swap_pages();
+ m_gc.state = GC_PROMOTE_SWAP;
+ break;
+
+ // Swap was discarded because the page being GC'ed had open records.
+ case GC_DISCARD_SWAP:
+ // Swap was successfully promoted.
+ case GC_PROMOTE_SWAP:
+ // Prepare to tag the page just GC'ed as swap.
+ m_gc.state = GC_TAG_NEW_SWAP;
+ break;
+
+ case GC_TAG_NEW_SWAP:
+ m_gc.state = GC_NEXT_PAGE;
+ break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+}
+
+
+// Initialize the filesystem.
+static ret_code_t init_execute(uint32_t prev_ret, fds_op_t * const p_op)
+{
+ ret_code_t ret = FDS_ERR_INTERNAL;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ // A previous operation has timed out.
+ m_flags.initializing = false;
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ switch (p_op->init.step)
+ {
+ case FDS_OP_INIT_TAG_SWAP:
+ {
+ // The page write offset was determined previously by pages_init().
+ p_op->init.step = FDS_OP_INIT_TAG_DATA;
+ ret = page_tag_write_swap();
+ } break;
+
+ case FDS_OP_INIT_TAG_DATA:
+ {
+ // Tag remaining erased pages as data.
+ bool write_reqd = false;
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ if (m_pages[i].page_type == FDS_PAGE_ERASED)
+ {
+ m_pages[i].page_type = FDS_PAGE_DATA;
+ write_reqd = true;
+ ret = page_tag_write_data(m_pages[i].p_addr);
+ break;
+ }
+ }
+ if (!write_reqd)
+ {
+ m_flags.initialized = true;
+ m_flags.initializing = false;
+ return FDS_OP_COMPLETED;
+ }
+ } break;
+
+ case FDS_OP_INIT_ERASE_SWAP:
+ {
+ // If the swap is going to be discarded then reset its write_offset.
+ p_op->init.step = FDS_OP_INIT_TAG_SWAP;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+
+ ret = nrf_fstorage_erase(&m_fs, (uint32_t)m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL);
+ } break;
+
+ case FDS_OP_INIT_PROMOTE_SWAP:
+ {
+ p_op->init.step = FDS_OP_INIT_TAG_SWAP;
+
+ // When promoting the swap, keep the write_offset set by pages_init().
+ ret = page_tag_write_data(m_swap_page.p_addr);
+
+ uint16_t const gc = m_gc.cur_page;
+ uint32_t const * const p_old_swap = m_swap_page.p_addr;
+
+ // Execute the swap.
+ m_swap_page.p_addr = m_pages[gc].p_addr;
+ m_pages[gc].p_addr = p_old_swap;
+
+ // Copy the offset from the swap to the new page.
+ m_pages[gc].write_offset = m_swap_page.write_offset;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+
+ m_pages[gc].page_type = FDS_PAGE_DATA;
+ } break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+
+ if (ret != FDS_SUCCESS)
+ {
+ // fstorage queue was full.
+ m_flags.initializing = false;
+ return FDS_ERR_BUSY;
+ }
+
+ return FDS_OP_EXECUTING;
+}
+
+
+// Executes write and update operations.
+static ret_code_t write_execute(uint32_t prev_ret, fds_op_t * const p_op)
+{
+ ret_code_t ret;
+ uint32_t * p_write_addr;
+ fds_page_t * const p_page = &m_pages[p_op->write.page];
+
+ // This must persist across calls.
+ static fds_record_desc_t desc = {0};
+ // When a record is updated, this variable will hold the page where the old
+ // copy was stored. This will be used to set the can_gc flag when the header is
+ // invalidated (FDS_OP_WRITE_FLAG_DIRTY).
+ static uint16_t page;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ // The previous operation has timed out, update offsets.
+ page_offsets_update(p_page, p_op);
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ // Compute the address where to write data.
+ p_write_addr = (uint32_t*)(p_page->p_addr + p_page->write_offset);
+
+ // Execute the current step of the operation, and set one to be executed next.
+ switch (p_op->write.step)
+ {
+ case FDS_OP_WRITE_FIND_RECORD:
+ {
+ // The first step of updating a record constists of locating the copy to be deleted.
+ // If the old copy couldn't be found for any reason then the update should fail.
+ // This prevents duplicates when queuing multiple updates of the same record.
+ desc.p_record = NULL;
+ desc.record_id = p_op->write.record_to_delete;
+
+ if (!record_find_by_desc(&desc, &page))
+ {
+ return FDS_ERR_NOT_FOUND;
+ }
+ // Setting the step is redundant since we are falling through.
+ }
+ // Fallthrough to FDS_OP_WRITE_HEADER_BEGIN.
+
+ case FDS_OP_WRITE_HEADER_BEGIN:
+ ret = record_header_write_begin(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_RECORD_ID:
+ ret = record_header_write_id(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_DATA:
+ ret = record_write_data(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_HEADER_FINALIZE:
+ ret = record_header_write_finalize(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_FLAG_DIRTY:
+ p_op->write.step = FDS_OP_WRITE_DONE;
+ ret = record_header_flag_dirty((uint32_t*)desc.p_record, page);
+ break;
+
+ case FDS_OP_WRITE_DONE:
+ ret = FDS_OP_COMPLETED;
+
+#if (FDS_CRC_CHECK_ON_WRITE)
+ if (!crc_verify_success(p_op->write.header.crc16,
+ p_op->write.header.length_words,
+ p_write_addr))
+ {
+ ret = FDS_ERR_CRC_CHECK_FAILED;
+ }
+#endif
+ break;
+
+ default:
+ ret = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ // An operation has either completed or failed. It may have failed because fstorage
+ // ran out of memory, or because the user tried to delete a record which did not exist.
+ if (ret != FDS_OP_EXECUTING)
+ {
+ // There won't be another callback for this operation, so update the page offset now.
+ page_offsets_update(p_page, p_op);
+ }
+
+ return ret;
+}
+
+
+static ret_code_t delete_execute(uint32_t prev_ret, fds_op_t * const p_op)
+{
+ ret_code_t ret;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ switch (p_op->del.step)
+ {
+ case FDS_OP_DEL_RECORD_FLAG_DIRTY:
+ p_op->del.step = FDS_OP_DEL_DONE;
+ ret = record_find_and_delete(p_op);
+ break;
+
+ case FDS_OP_DEL_FILE_FLAG_DIRTY:
+ ret = file_find_and_delete(p_op);
+ if (ret == FDS_ERR_NOT_FOUND)
+ {
+ // No more records could be found.
+ // There won't be another callback for this operation, so return now.
+ ret = FDS_OP_COMPLETED;
+ }
+ break;
+
+ case FDS_OP_DEL_DONE:
+ ret = FDS_OP_COMPLETED;
+ break;
+
+ default:
+ ret = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ return ret;
+}
+
+
+static ret_code_t gc_execute(uint32_t prev_ret)
+{
+ ret_code_t ret;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ if (m_gc.resume)
+ {
+ m_gc.resume = false;
+ }
+ else
+ {
+ gc_state_advance();
+ }
+
+ switch (m_gc.state)
+ {
+ case GC_NEXT_PAGE:
+ ret = gc_next_page();
+ break;
+
+ case GC_FIND_NEXT_RECORD:
+ ret = gc_record_find_next();
+ break;
+
+ case GC_COPY_RECORD:
+ ret = gc_record_copy();
+ break;
+
+ case GC_ERASE_PAGE:
+ ret = gc_page_erase();
+ break;
+
+ case GC_PROMOTE_SWAP:
+ ret = gc_swap_promote();
+ break;
+
+ case GC_TAG_NEW_SWAP:
+ ret = gc_tag_new_swap();
+ break;
+
+ default:
+ // Should not happen.
+ ret = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ // Either FDS_OP_EXECUTING, FDS_OP_COMPLETED, FDS_ERR_BUSY or FDS_ERR_INTERNAL.
+ return ret;
+}
+
+
+static void queue_process(ret_code_t result)
+{
+ static fds_op_t * m_p_cur_op; // Current fds operation.
+ static nrf_atfifo_item_get_t m_iget_ctx; // Queue context for the current operation.
+
+ while (true)
+ {
+ if (m_p_cur_op == NULL)
+ {
+ // Load the next from the queue if no operation is being executed.
+ m_p_cur_op = queue_load(&m_iget_ctx);
+ }
+
+ /* We can reach here in three ways:
+ * from queue_start(): something was just queued
+ * from the fstorage event handler: an operation is being executed
+ * looping: we only loop if there are operations still in the queue
+ *
+ * In all these three cases, m_p_cur_op != NULL.
+ */
+ ASSERT(m_p_cur_op != NULL);
+
+ switch (m_p_cur_op->op_code)
+ {
+ case FDS_OP_INIT:
+ result = init_execute(result, m_p_cur_op);
+ break;
+
+ case FDS_OP_WRITE:
+ case FDS_OP_UPDATE:
+ result = write_execute(result, m_p_cur_op);
+ break;
+
+ case FDS_OP_DEL_RECORD:
+ case FDS_OP_DEL_FILE:
+ result = delete_execute(result, m_p_cur_op);
+ break;
+
+ case FDS_OP_GC:
+ result = gc_execute(result);
+ break;
+
+ default:
+ result = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ if (result == FDS_OP_EXECUTING)
+ {
+ // The operation has not completed yet. Wait for the next system event.
+ break;
+ }
+
+ // The operation has completed (either successfully or with an error).
+ // - send an event to the user
+ // - free the operation buffer
+ // - execute any other queued operations
+
+ fds_evt_t evt =
+ {
+ // The operation might have failed for one of the following reasons:
+ // FDS_ERR_BUSY - flash subsystem can't accept the operation
+ // FDS_ERR_OPERATION_TIMEOUT - flash subsystem timed out
+ // FDS_ERR_CRC_CHECK_FAILED - a CRC check failed
+ // FDS_ERR_NOT_FOUND - no record found (delete/update)
+ .result = (result == FDS_OP_COMPLETED) ? FDS_SUCCESS : result,
+ };
+
+ event_prepare(m_p_cur_op, &evt);
+ event_send(&evt);
+
+ // Zero the pointer to the current operation so that this function
+ // will fetch a new one from the queue next time it is run.
+ m_p_cur_op = NULL;
+
+ // The result of the operation must be reset upon re-entering the loop to ensure
+ // the next operation won't be affected by eventual errors in previous operations.
+ result = NRF_SUCCESS;
+
+ // Free the queue element used by the current operation.
+ queue_free(&m_iget_ctx);
+
+ if (!queue_has_next())
+ {
+ // No more elements left. Nothing to do.
+ break;
+ }
+ }
+}
+
+
+static void queue_start(void)
+{
+ if (!nrf_atomic_u32_fetch_add(&m_queued_op_cnt, 1))
+ {
+ queue_process(NRF_SUCCESS);
+ }
+}
+
+
+static void fs_event_handler(nrf_fstorage_evt_t * p_evt)
+{
+ queue_process(p_evt->result);
+}
+
+
+// Enqueues write and update operations.
+static ret_code_t write_enqueue(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record,
+ fds_reserve_token_t const * const p_tok,
+ fds_op_code_t op_code)
+{
+ ret_code_t ret;
+ uint16_t page;
+ uint16_t crc = 0;
+ uint16_t length_words = 0;
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_record == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ if ((p_record->file_id == FDS_FILE_ID_INVALID) ||
+ (p_record->key == FDS_RECORD_KEY_DIRTY))
+ {
+ return FDS_ERR_INVALID_ARG;
+ }
+
+ if (!is_word_aligned(p_record->data.p_data))
+ {
+ return FDS_ERR_UNALIGNED_ADDR;
+ }
+
+ // No space was previously reserved in flash for this operation.
+ if (p_tok == NULL)
+ {
+ // Find a page where to write data.
+ length_words = p_record->data.length_words;
+ ret = write_space_reserve(length_words, &page);
+
+ if (ret != FDS_SUCCESS)
+ {
+ // There is either not enough space in flash (FDS_ERR_NO_SPACE_IN_FLASH) or
+ // the record exceeds the size of virtual page (FDS_ERR_RECORD_TOO_LARGE).
+ return ret;
+ }
+ }
+ else
+ {
+ page = p_tok->page;
+ length_words = p_tok->length_words;
+ }
+
+ // Get a buffer on the queue of operations.
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ CRITICAL_SECTION_ENTER();
+ write_space_free(length_words, page);
+ CRITICAL_SECTION_EXIT();
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ // Initialize the operation.
+ p_op->op_code = op_code;
+ p_op->write.step = FDS_OP_WRITE_HEADER_BEGIN;
+ p_op->write.page = page;
+ p_op->write.p_data = p_record->data.p_data;
+ p_op->write.header.record_id = record_id_new();
+ p_op->write.header.file_id = p_record->file_id;
+ p_op->write.header.record_key = p_record->key;
+ p_op->write.header.length_words = length_words;
+
+ if (op_code == FDS_OP_UPDATE)
+ {
+ p_op->write.step = FDS_OP_WRITE_FIND_RECORD;
+ // Save the record ID of the record to be updated.
+ p_op->write.record_to_delete = p_desc->record_id;
+ }
+
+#if (FDS_CRC_CHECK_ON_READ)
+ // First, compute the CRC for the first 6 bytes of the header which contain the
+ // record key, length and file ID, then, compute the CRC of the record ID (4 bytes).
+ crc = crc16_compute((uint8_t*)&p_op->write.header, 6, NULL);
+ crc = crc16_compute((uint8_t*)&p_op->write.header.record_id, 4, &crc);
+
+ // Compute the CRC for the record data.
+ crc = crc16_compute((uint8_t*)p_record->data.p_data,
+ p_record->data.length_words * sizeof(uint32_t), &crc);
+#endif
+
+ p_op->write.header.crc16 = crc;
+
+ queue_buf_store(&iput_ctx);
+
+ // Initialize the record descriptor, if provided.
+ if (p_desc != NULL)
+ {
+ p_desc->p_record = NULL;
+ // Don't invoke record_id_new() again !
+ p_desc->record_id = p_op->write.header.record_id;
+ p_desc->record_is_open = false;
+ p_desc->gc_run_count = m_gc.run_count;
+ }
+
+ // Start processing the queue, if necessary.
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_register(fds_cb_t cb)
+{
+ ret_code_t ret;
+
+ if (m_users == FDS_MAX_USERS)
+ {
+ ret = FDS_ERR_USER_LIMIT_REACHED;
+ }
+ else
+ {
+ m_cb_table[m_users] = cb;
+ (void) nrf_atomic_u32_add(&m_users, 1);
+
+ ret = FDS_SUCCESS;
+ }
+
+ return ret;
+}
+
+
+static uint32_t flash_end_addr(void)
+{
+ uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
+ uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;
+#ifndef NRF52810_XXAA
+ uint32_t const code_sz = NRF_FICR->CODESIZE;
+#else
+ // Number of flash pages, necessary to emulate the NRF52810 on NRF52832.
+ uint32_t const code_sz = 48;
+#endif
+
+ return (bootloader_addr != 0xFFFFFFFF) ? bootloader_addr : (code_sz * page_sz);
+}
+
+
+static void flash_bounds_set(void)
+{
+ uint32_t flash_size = (FDS_PHY_PAGES * FDS_PHY_PAGE_SIZE * sizeof(uint32_t));
+ m_fs.end_addr = flash_end_addr();
+ m_fs.start_addr = m_fs.end_addr - flash_size;
+}
+
+
+static ret_code_t flash_subsystem_init(void)
+{
+ flash_bounds_set();
+
+ #if (FDS_BACKEND == NRF_FSTORAGE_SD)
+ return nrf_fstorage_init(&m_fs, &nrf_fstorage_sd, NULL);
+ #elif (FDS_BACKEND == NRF_FSTORAGE_NVMC)
+ return nrf_fstorage_init(&m_fs, &nrf_fstorage_nvmc, NULL);
+ #else
+ #error Invalid FDS_BACKEND.
+ #endif
+}
+
+
+static void queue_init(void)
+{
+ (void) NRF_ATFIFO_INIT(m_queue);
+}
+
+
+ret_code_t fds_init(void)
+{
+ ret_code_t ret;
+ fds_evt_t const evt_success =
+ {
+ .id = FDS_EVT_INIT,
+ .result = FDS_SUCCESS,
+ };
+
+ if (m_flags.initialized)
+ {
+ // No initialization is necessary. Notify the application immediately.
+ event_send(&evt_success);
+ return FDS_SUCCESS;
+ }
+
+ if (nrf_atomic_flag_set_fetch(&m_flags.initializing))
+ {
+ // If we were already initializing, return.
+ return FDS_SUCCESS;
+ }
+
+ // Otherwise, the flag is set and we proceed to initialization.
+
+ ret = flash_subsystem_init();
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ queue_init();
+
+ // Initialize the page structure (m_pages), and determine which
+ // initialization steps are required given the current state of the filesystem.
+
+ fds_init_opts_t init_opts = pages_init();
+
+ switch (init_opts)
+ {
+ case NO_PAGES:
+ case NO_SWAP:
+ return FDS_ERR_NO_PAGES;
+
+ case ALREADY_INSTALLED:
+ {
+ // No initialization is necessary. Notify the application immediately.
+ m_flags.initialized = true;
+ m_flags.initializing = false;
+ event_send(&evt_success);
+ return FDS_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+
+ // A write operation is necessary to initialize the fileystem.
+
+ nrf_atfifo_item_put_t iput_ctx;
+
+ fds_op_t * p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_INIT;
+
+ switch (init_opts)
+ {
+ case FRESH_INSTALL:
+ case TAG_SWAP:
+ p_op->init.step = FDS_OP_INIT_TAG_SWAP;
+ break;
+
+ case PROMOTE_SWAP:
+ case PROMOTE_SWAP_INST:
+ p_op->init.step = FDS_OP_INIT_PROMOTE_SWAP;
+ break;
+
+ case DISCARD_SWAP:
+ p_op->init.step = FDS_OP_INIT_ERASE_SWAP;
+ break;
+
+ case TAG_DATA:
+ case TAG_DATA_INST:
+ p_op->init.step = FDS_OP_INIT_TAG_DATA;
+ break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+
+ queue_buf_store(&iput_ctx);
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_record_open(fds_record_desc_t * const p_desc,
+ fds_flash_record_t * const p_flash_rec)
+{
+ uint16_t page;
+
+ if ((p_desc == NULL) || (p_flash_rec == NULL))
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ // Find the record if necessary.
+ if (record_find_by_desc(p_desc, &page))
+ {
+ fds_header_t const * const p_header = (fds_header_t*)p_desc->p_record;
+
+#if (FDS_CRC_CHECK_ON_READ)
+ if (!crc_verify_success(p_header->crc16,
+ p_header->length_words,
+ p_desc->p_record))
+ {
+ return FDS_ERR_CRC_CHECK_FAILED;
+ }
+#endif
+
+ (void) nrf_atomic_u32_add(&m_pages[page].records_open, 1);
+
+ // Initialize p_flash_rec.
+ p_flash_rec->p_header = p_header;
+ p_flash_rec->p_data = (p_desc->p_record + FDS_HEADER_SIZE);
+
+ // Set the record as open in the descriptor.
+ p_desc->record_is_open = true;
+
+ return FDS_SUCCESS;
+ }
+
+ // The record could not be found.
+ // It either never existed or it has been deleted.
+ return FDS_ERR_NOT_FOUND;
+}
+
+
+ret_code_t fds_record_close(fds_record_desc_t * const p_desc)
+{
+ ret_code_t ret;
+ uint16_t page;
+
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ if (record_find_by_desc((fds_record_desc_t*)p_desc, &page))
+ {
+ CRITICAL_SECTION_ENTER();
+ if ((m_pages[page].records_open > 0) && (p_desc->record_is_open))
+ {
+
+ m_pages[page].records_open--;
+ p_desc->record_is_open = false;
+
+ ret = FDS_SUCCESS;
+ }
+ else
+ {
+ ret = FDS_ERR_NO_OPEN_RECORDS;
+ }
+ CRITICAL_SECTION_EXIT();
+ }
+ else
+ {
+ ret = FDS_ERR_NOT_FOUND;
+ }
+
+ return ret;
+}
+
+
+ret_code_t fds_reserve(fds_reserve_token_t * const p_tok, uint16_t length_words)
+{
+ ret_code_t ret;
+ uint16_t page;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_tok == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ ret = write_space_reserve(length_words, &page);
+
+ if (ret == FDS_SUCCESS)
+ {
+ p_tok->page = page;
+ p_tok->length_words = length_words;
+ }
+
+ return ret;
+}
+
+
+ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_tok)
+{
+ ret_code_t ret;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_tok == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ if (p_tok->page > FDS_DATA_PAGES)
+ {
+ // The page does not exist. This shouldn't happen.
+ return FDS_ERR_INVALID_ARG;
+ }
+
+ fds_page_t const * const p_page = &m_pages[p_tok->page];
+
+ CRITICAL_SECTION_ENTER();
+ if ((FDS_HEADER_SIZE + p_tok->length_words) <= p_page->words_reserved)
+ {
+ // Free reserved space.
+ write_space_free(p_tok->length_words, p_tok->page);
+
+ // Clean the token.
+ p_tok->page = 0;
+ p_tok->length_words = 0;
+ ret = FDS_SUCCESS;
+ }
+ else
+ {
+ // We are trying to cancel a reservation of more words than how many are
+ // currently reserved on the page. Clearly, this shouldn't happen.
+ ret = FDS_ERR_INVALID_ARG;
+ }
+ CRITICAL_SECTION_EXIT();
+
+ return ret;
+}
+
+
+ret_code_t fds_record_write(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record)
+{
+ return write_enqueue(p_desc, p_record, NULL, FDS_OP_WRITE);
+}
+
+
+ret_code_t fds_record_write_reserved(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record,
+ fds_reserve_token_t const * const p_tok)
+{
+ // A NULL token is not allowed when writing to a reserved space.
+ if (p_tok == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ return write_enqueue(p_desc, p_record, p_tok, FDS_OP_WRITE);
+}
+
+
+ret_code_t fds_record_update(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record)
+{
+ // A NULL descriptor is not allowed when updating a record.
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ return write_enqueue(p_desc, p_record, NULL, FDS_OP_UPDATE);
+}
+
+
+ret_code_t fds_record_delete(fds_record_desc_t * const p_desc)
+{
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_DEL_RECORD;
+ p_op->del.step = FDS_OP_DEL_RECORD_FLAG_DIRTY;
+ p_op->del.record_to_delete = p_desc->record_id;
+
+ queue_buf_store(&iput_ctx);
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_file_delete(uint16_t file_id)
+{
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (file_id == FDS_FILE_ID_INVALID)
+ {
+ return FDS_ERR_INVALID_ARG;
+ }
+
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_DEL_FILE;
+ p_op->del.step = FDS_OP_DEL_FILE_FLAG_DIRTY;
+ p_op->del.file_id = file_id;
+
+ queue_buf_store(&iput_ctx);
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_gc(void)
+{
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_GC;
+
+ queue_buf_store(&iput_ctx);
+
+ if (m_gc.state != GC_BEGIN)
+ {
+ // Resume GC by retrying the last step.
+ m_gc.resume = true;
+ }
+
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(NULL, NULL, p_desc, p_token);
+}
+
+
+ret_code_t fds_record_find(uint16_t file_id,
+ uint16_t record_key,
+ fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(&file_id, &record_key, p_desc, p_token);
+}
+
+
+ret_code_t fds_record_find_by_key(uint16_t record_key,
+ fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(NULL, &record_key, p_desc, p_token);
+}
+
+
+ret_code_t fds_record_find_in_file(uint16_t file_id,
+ fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(&file_id, NULL, p_desc, p_token);
+}
+
+
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
+ uint32_t record_id)
+{
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ // Zero the descriptor and set the record_id field.
+ memset(p_desc, 0x00, sizeof(fds_record_desc_t));
+ p_desc->record_id = record_id;
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
+ uint32_t * const p_record_id)
+{
+ if ((p_desc == NULL) || (p_record_id == NULL))
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ *p_record_id = p_desc->record_id;
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_stat(fds_stat_t * const p_stat)
+{
+ uint16_t const words_in_page = FDS_PAGE_SIZE;
+ // The largest number of free contiguous words on any page.
+ uint16_t contig_words = 0;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_stat == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ memset(p_stat, 0x00, sizeof(fds_stat_t));
+
+ p_stat->pages_available = FDS_VIRTUAL_PAGES;
+
+ for (uint16_t page = 0; page < FDS_DATA_PAGES; page++)
+ {
+ uint16_t const words_used = m_pages[page].write_offset + m_pages[page].words_reserved;
+
+ if (page_identify(m_pages[page].p_addr) == FDS_PAGE_UNDEFINED)
+ {
+ p_stat->pages_available--;
+ }
+
+ p_stat->open_records += m_pages[page].records_open;
+ p_stat->words_reserved += m_pages[page].words_reserved;
+ p_stat->words_used += words_used;
+
+ contig_words = (words_in_page - words_used);
+ if (contig_words > p_stat->largest_contig)
+ {
+ p_stat->largest_contig = contig_words;
+ }
+
+ records_stat(page,
+ &p_stat->valid_records,
+ &p_stat->dirty_records,
+ &p_stat->freeable_words,
+ &p_stat->corruption);
+ }
+
+ return FDS_SUCCESS;
+}
+
+#endif //NRF_MODULE_ENABLED(FDS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h
new file mode 100644
index 0000000..09d1eea
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h
@@ -0,0 +1,700 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef FDS_H__
+#define FDS_H__
+
+/**
+ * @defgroup fds Flash Data Storage
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Flash Data Storage (FDS).
+ *
+ * @details Flash Data Storage is a minimalistic, record-oriented file system for the on-chip
+ * flash. Files are stored as a collection of records of variable length. FDS supports
+ * synchronous read operations and asynchronous write operations (write, update,
+ * and delete). FDS can be used from multiple threads.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Invalid file ID.
+ *
+ * This value must not be used as a file ID by the application.
+ */
+#define FDS_FILE_ID_INVALID (0xFFFF)
+
+
+/**@brief Record key for deleted records.
+ *
+ * This key is used to flag a record as "dirty", which means that it should be removed during
+ * the next garbage collection. This value must not be used as a record key by the application.
+ */
+#define FDS_RECORD_KEY_DIRTY (0x0000)
+
+
+/**@brief FDS return values.
+ */
+enum
+{
+ FDS_SUCCESS = NRF_SUCCESS, //!< The operation completed successfully.
+ FDS_ERR_OPERATION_TIMEOUT, //!< Error. The operation timed out.
+ FDS_ERR_NOT_INITIALIZED, //!< Error. The module has not been initialized.
+ FDS_ERR_UNALIGNED_ADDR, //!< Error. The input data is not aligned to a word boundary.
+ FDS_ERR_INVALID_ARG, //!< Error. The parameter contains invalid data.
+ FDS_ERR_NULL_ARG, //!< Error. The parameter is NULL.
+ FDS_ERR_NO_OPEN_RECORDS, //!< Error. The record is not open, so it cannot be closed.
+ FDS_ERR_NO_SPACE_IN_FLASH, //!< Error. There is no space in flash memory.
+ FDS_ERR_NO_SPACE_IN_QUEUES, //!< Error. There is no space in the internal queues.
+ FDS_ERR_RECORD_TOO_LARGE, //!< Error. The record exceeds the maximum allowed size.
+ FDS_ERR_NOT_FOUND, //!< Error. The record was not found.
+ FDS_ERR_NO_PAGES, //!< Error. No flash pages are available.
+ FDS_ERR_USER_LIMIT_REACHED, //!< Error. The maximum number of users has been reached.
+ FDS_ERR_CRC_CHECK_FAILED, //!< Error. The CRC check failed.
+ FDS_ERR_BUSY, //!< Error. The underlying flash subsystem was busy.
+ FDS_ERR_INTERNAL, //!< Error. An internal error occurred.
+};
+
+
+/**@brief The record metadata as stored in flash.
+ * @warning Do not edit or reorder the fields in this structure.
+ */
+typedef struct
+{
+ uint16_t record_key; //!< The record key.
+ uint16_t length_words; //!< The length of the record data (in 4-byte words).
+ uint16_t file_id; //!< The ID of the file that the record belongs to.
+ uint16_t crc16; //!< CRC16-CCITT check value.
+ /* The CRC is calculated over the entire record as stored in flash,
+ * including the record metadata except the CRC field itself.
+ */
+ uint32_t record_id; //!< The unique record ID (32 bits).
+} fds_header_t;
+
+
+/**@brief The record descriptor structure that is used to manipulate records.
+ *
+ * This structure is used by the FDS module. You must provide the descriptor to the module when
+ * you manipulate existing records. However, you should never modify it or use any of its fields.
+ *
+ * @note Never reuse the same descriptor for different records.
+ */
+typedef struct
+{
+ uint32_t record_id; //!< The unique record ID.
+ uint32_t const * p_record; //!< The last known location of the record in flash.
+ uint16_t gc_run_count; //!< Number of times garbage collection has been run.
+ bool record_is_open; //!< Whether the record is currently open.
+} fds_record_desc_t;
+
+
+/**@brief Structure that can be used to read the contents of a record stored in flash.
+ *
+ * This structure does not reflect the physical layout of a record in flash, but it points
+ * to the locations where the record header (metadata) and the record data are stored.
+ */
+typedef struct
+{
+ fds_header_t const * p_header; //!< Location of the record header in flash.
+ void const * p_data; //!< Location of the record data in flash.
+} fds_flash_record_t;
+
+
+/**@brief A record to be written to flash. */
+typedef struct
+{
+ uint16_t file_id; //!< The ID of the file that the record belongs to.
+ uint16_t key; //!< The record key.
+ struct
+ {
+ void const * p_data;
+ uint32_t length_words;
+ } data;
+} fds_record_t;
+
+
+/**@brief A token to a reserved space in flash, created by @ref fds_reserve.
+ *
+ * This token can be used to write the record in the reserved space (@ref fds_record_write_reserved)
+ * or to cancel the reservation (@ref fds_reserve_cancel).
+ */
+typedef struct
+{
+ uint16_t page; //!< The logical ID of the page where space was reserved.
+ uint16_t length_words; //!< The amount of space reserved (in 4-byte words).
+} fds_reserve_token_t;
+
+
+/**@brief A token to keep information about the progress of @ref fds_record_find,
+ * @ref fds_record_find_by_key, and @ref fds_record_find_in_file.
+ *
+ * @note Always zero-initialize the token before using it for the first time.
+ * @note Never reuse the same token to search for different records.
+ */
+typedef struct
+{
+ uint32_t const * p_addr;
+ uint16_t page;
+} fds_find_token_t;
+
+
+/**@brief FDS event IDs.
+ */
+typedef enum
+{
+ FDS_EVT_INIT, //!< Event for @ref fds_init.
+ FDS_EVT_WRITE, //!< Event for @ref fds_record_write and @ref fds_record_write_reserved.
+ FDS_EVT_UPDATE, //!< Event for @ref fds_record_update.
+ FDS_EVT_DEL_RECORD, //!< Event for @ref fds_record_delete.
+ FDS_EVT_DEL_FILE, //!< Event for @ref fds_file_delete.
+ FDS_EVT_GC //!< Event for @ref fds_gc.
+} fds_evt_id_t;
+
+
+ANON_UNIONS_ENABLE;
+
+/**@brief An FDS event. */
+typedef struct
+{
+ fds_evt_id_t id; //!< The event ID. See @ref fds_evt_id_t.
+ ret_code_t result; //!< The result of the operation related to this event.
+ union
+ {
+ struct
+ {
+ uint32_t record_id;
+ uint16_t file_id;
+ uint16_t record_key;
+ bool is_record_updated;
+ } write; //!< Information for @ref FDS_EVT_WRITE and @ref FDS_EVT_UPDATE events.
+ struct
+ {
+ uint32_t record_id;
+ uint16_t file_id;
+ uint16_t record_key;
+ } del; //!< Information for @ref FDS_EVT_DEL_RECORD and @ref FDS_EVT_DEL_FILE events.
+ };
+} fds_evt_t;
+
+ANON_UNIONS_DISABLE;
+
+
+/**@brief File system statistics. */
+typedef struct
+{
+ uint16_t pages_available; //!< The number of pages available.
+ uint16_t open_records; //!< The number of open records.
+ uint16_t valid_records; //!< The number of valid records.
+ uint16_t dirty_records; //!< The number of deleted ("dirty") records.
+ uint16_t words_reserved; //!< The number of words reserved by @ref fds_reserve().
+
+ /**@brief The number of words written to flash, including those reserved for future writes. */
+ uint16_t words_used;
+
+ /**@brief The largest number of free contiguous words in the file system.
+ *
+ * This number indicates the largest record that can be stored by FDS.
+ * It takes into account all reservations for future writes.
+ */
+ uint16_t largest_contig;
+
+ /**@brief The largest number of words that can be reclaimed by garbage collection.
+ *
+ * The actual amount of space freed by garbage collection might be less than this value if
+ * records are open while garbage collection is run.
+ */
+ uint16_t freeable_words;
+
+ /**@brief Filesystem corruption has been detected.
+ *
+ * One or more corrupted records were detected. FDS will heal the filesystem automatically
+ * next time garbage collection is run, but some data may be lost.
+ *
+ * @note: This flag is unrelated to CRC failures.
+ */
+ bool corruption;
+} fds_stat_t;
+
+
+/**@brief FDS event handler function prototype.
+ *
+ * @param p_evt The event.
+ */
+typedef void (*fds_cb_t)(fds_evt_t const * p_evt);
+
+
+/**@brief Function for registering an FDS event handler.
+ *
+ * The maximum amount of handlers that can be registered can be configured by changing the value
+ * of @ref FDS_MAX_USERS in fds_config.h.
+ *
+ * @param[in] cb The event handler function.
+ *
+ * @retval FDS_SUCCESS If the event handler was registered successfully.
+ * @retval FDS_ERR_USER_LIMIT_REACHED If the maximum number of registered callbacks is reached.
+ */
+ret_code_t fds_register(fds_cb_t cb);
+
+
+/**@brief Function for initializing the module.
+ *
+ * This function initializes the module and installs the file system (unless it is installed
+ * already).
+ *
+ * This function is asynchronous. Completion is reported through an event. Make sure to call
+ * @ref fds_register before calling @ref fds_init so that you receive the completion event.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NO_PAGES If there is no space available in flash memory to install the
+ * file system.
+ */
+ret_code_t fds_init(void);
+
+
+/**@brief Function for writing a record to flash.
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Some modules need exclusive use of certain file IDs and record keys.
+ * See @ref lib_fds_functionality_keys for details.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to
+ * the registered event handler function.
+ *
+ * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not
+ * need the descriptor.
+ * @param[in] p_record The record to be written to flash.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_record is NULL.
+ * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid.
+ * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record
+ * chunks than can be buffered.
+ * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the
+ * record.
+ */
+ret_code_t fds_record_write(fds_record_desc_t * p_desc,
+ fds_record_t const * p_record);
+
+
+/**@brief Function for reserving space in flash.
+ *
+ * This function can be used to reserve space in flash memory. To write a record into the reserved
+ * space, use @ref fds_record_write_reserved. Alternatively, use @ref fds_reserve_cancel to cancel
+ * a reservation.
+ *
+ * Note that this function does not write any data to flash.
+ *
+ * @param[out] p_token A token that can be used to write a record in the reserved space or
+ * cancel the reservation.
+ * @param[in] length_words The length of the record data (in 4-byte words).
+ *
+ * @retval FDS_SUCCESS If the flash space was reserved successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record length exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the
+ * record.
+ */
+ret_code_t fds_reserve(fds_reserve_token_t * p_token, uint16_t length_words);
+
+
+/**@brief Function for canceling an @ref fds_reserve operation.
+ *
+ * @param[in] p_token The token that identifies the reservation, produced by @ref fds_reserve.
+ *
+ * @retval FDS_SUCCESS If the reservation was canceled.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address.
+ * @retval FDS_ERR_INVALID_ARG If @p p_token contains invalid data.
+ */
+ret_code_t fds_reserve_cancel(fds_reserve_token_t * p_token);
+
+
+/**@brief Function for writing a record to a space in flash that was reserved using
+ * @ref fds_reserve.
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @note
+ * This function behaves similarly to @ref fds_record_write, with the exception that it never
+ * fails with the error @ref FDS_ERR_NO_SPACE_IN_FLASH.
+ *
+ * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not
+ * need the descriptor.
+ * @param[in] p_record The record to be written to flash.
+ * @param[in] p_token The token that identifies the space reserved in flash.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address.
+ * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid.
+ * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record
+ * chunks than can be buffered.
+ */
+ret_code_t fds_record_write_reserved(fds_record_desc_t * p_desc,
+ fds_record_t const * p_record,
+ fds_reserve_token_t const * p_token);
+
+
+/**@brief Function for deleting a record.
+ *
+ * Deleted records cannot be located using @ref fds_record_find, @ref fds_record_find_by_key, or
+ * @ref fds_record_find_in_file. Additionally, they can no longer be opened using
+ * @ref fds_record_open.
+ *
+ * Note that deleting a record does not free the space it occupies in flash memory.
+ * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in] p_desc The descriptor of the record that should be deleted.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If the specified record descriptor @p p_desc is NULL.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full.
+ */
+ret_code_t fds_record_delete(fds_record_desc_t * p_desc);
+
+
+/**@brief Function for deleting all records in a file.
+ *
+ * This function deletes a file, including all its records. Deleted records cannot be located
+ * using @ref fds_record_find, @ref fds_record_find_by_key, or @ref fds_record_find_in_file.
+ * Additionally, they can no longer be opened using @ref fds_record_open.
+ *
+ * Note that deleting records does not free the space they occupy in flash memory.
+ * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in] file_id The ID of the file to be deleted.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_INVALID_ARG If the specified @p file_id is invalid.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full.
+ */
+ret_code_t fds_file_delete(uint16_t file_id);
+
+
+/**@brief Function for updating a record.
+ *
+ * Updating a record first writes a new record (@p p_record) to flash and then deletes the
+ * old record (identified by @p p_desc).
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in, out] p_desc The descriptor of the record to update. When the function
+ * returns with FDS_SUCCESS, this parameter contains the
+ * descriptor of the newly written record.
+ * @param[in] p_record The updated record to be written to flash.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid.
+ * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record
+ * chunks than can be buffered.
+ * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the
+ * updated record.
+ */
+ret_code_t fds_record_update(fds_record_desc_t * p_desc,
+ fds_record_t const * p_record);
+
+
+/**@brief Function for iterating through all records in flash.
+ *
+ * To search for the next record, call the function again and supply the same @ref fds_find_token_t
+ * structure to resume searching from the last record that was found.
+ *
+ * Note that the order with which records are iterated is not defined.
+ *
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no matching record was found.
+ */
+ret_code_t fds_record_iterate(fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for searching for records with a given record key in a file.
+ *
+ * This function finds the first record in a file that has the given record key. To search for the
+ * next record with the same key in the file, call the function again and supply the same
+ * @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in] file_id The file ID.
+ * @param[in] record_key The record key.
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no matching record was found.
+ */
+ret_code_t fds_record_find(uint16_t file_id,
+ uint16_t record_key,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for searching for records with a given record key.
+ *
+ * This function finds the first record with a given record key, independent of the file it
+ * belongs to. To search for the next record with the same key, call the function again and supply
+ * the same @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in] record_key The record key.
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no record with the given key was found.
+ */
+ret_code_t fds_record_find_by_key(uint16_t record_key,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for searching for any record in a file.
+ *
+ * This function finds the first record in a file, independent of its record key.
+ * To search for the next record in the same file, call the function again and supply the same
+ * @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in] file_id The file ID.
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no matching record was found.
+ */
+ret_code_t fds_record_find_in_file(uint16_t file_id,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for opening a record for reading.
+ *
+ * This function opens a record that is stored in flash, so that it can be read. The function
+ * initializes an @ref fds_flash_record_t structure, which can be used to access the record data as
+ * well as its associated metadata. The pointers provided in the @ref fds_flash_record_t structure
+ * are pointers to flash memory.
+ *
+ * Opening a record with @ref fds_record_open prevents garbage collection to run on the virtual
+ * flash page in which record is stored, so that the contents of the memory pointed by fields in
+ * @ref fds_flash_record_t are guaranteed to remain unmodified as long as the record is kept open.
+ *
+ * When you are done reading a record, call @ref fds_record_close to close it. Garbage collection
+ * can then reclaim space on the virtual page where the record is stored. Note that you must
+ * provide the same descriptor for @ref fds_record_close as you did for this function.
+ *
+ * @param[in] p_desc The descriptor of the record to open.
+ * @param[out] p_flash_record The record, as stored in flash.
+ *
+ * @retval FDS_SUCCESS If the record was opened successfully.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_flash_record is NULL.
+ * @retval FDS_ERR_NOT_FOUND If the record was not found. It might have been deleted, or
+ * it might not have been written yet.
+ * @retval FDS_ERR_CRC_CHECK_FAILED If the CRC check for the record failed.
+ */
+ret_code_t fds_record_open(fds_record_desc_t * p_desc,
+ fds_flash_record_t * p_flash_record);
+
+
+/**@brief Function for closing a record.
+ *
+ * Closing a record allows garbage collection to run on the virtual page in which the record is
+ * stored (if no other records remain open on that page). The descriptor passed as an argument
+ * must be the same as the one used to open the record using @ref fds_record_open.
+ *
+ * Note that closing a record does not invalidate its descriptor. You can still supply the
+ * descriptor to all functions that accept a record descriptor as a parameter.
+ *
+ * @param[in] p_desc The descriptor of the record to close.
+ *
+ * @retval FDS_SUCCESS If the record was closed successfully.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL.
+ * @retval FDS_ERR_NO_OPEN_RECORDS If the record is not open.
+ * @retval FDS_ERR_NOT_FOUND If the record could not be found.
+ */
+ret_code_t fds_record_close(fds_record_desc_t * p_desc);
+
+
+/**@brief Function for running garbage collection.
+ *
+ * Garbage collection reclaims the flash space that is occupied by records that have been deleted,
+ * or that failed to be completely written due to, for example, a power loss.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full.
+ */
+ret_code_t fds_gc(void);
+
+
+/**@brief Function for obtaining a descriptor from a record ID.
+ *
+ * This function can be used to reconstruct a descriptor from a record ID, like the one that is
+ * passed to the callback function.
+ *
+ * @note
+ * This function does not check whether a record with the given record ID exists.
+ * If a non-existing record ID is supplied, the resulting descriptor is invalid and will cause
+ * other functions to fail when it is supplied as parameter.
+ *
+ * @param[out] p_desc The descriptor of the record with the given record ID.
+ * @param[in] record_id The record ID for which a descriptor should be returned.
+ *
+ * @retval FDS_SUCCESS If a descriptor was returned.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL.
+ */
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * p_desc,
+ uint32_t record_id);
+
+
+/**@brief Function for obtaining a record ID from a record descriptor.
+ *
+ * This function can be used to extract a record ID from a descriptor. For example, you could use
+ * it in the callback function to compare the record ID of an event to the record IDs of the
+ * records for which you have a descriptor.
+ *
+ * @warning
+ * This function does not check whether the record descriptor is valid. If the descriptor is not
+ * initialized or has been tampered with, the resulting record ID might be invalid.
+ *
+ * @param[in] p_desc The descriptor from which the record ID should be extracted.
+ * @param[out] p_record_id The record ID that is contained in the given descriptor.
+ *
+ * @retval FDS_SUCCESS If a record ID was returned.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_record_id is NULL.
+ */
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * p_desc,
+ uint32_t * p_record_id);
+
+
+/**@brief Function for retrieving file system statistics.
+ *
+ * This function retrieves file system statistics, such as the number of open records, the space
+ * that can be reclaimed by garbage collection, and others.
+ *
+ * @param[out] p_stat File system statistics.
+ *
+ * @retval FDS_SUCCESS If the statistics were returned successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_stat is NULL.
+ */
+ret_code_t fds_stat(fds_stat_t * p_stat);
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FDS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h
new file mode 100644
index 0000000..7502b43
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef FDS_INTERNAL_DEFS_H__
+#define FDS_INTERNAL_DEFS_H__
+#include "sdk_config.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined (FDS_THREADS)
+ #include "nrf_soc.h"
+ #include "app_util_platform.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FDS_PAGE_TAG_SIZE (2) // Page tag size, in 4-byte words.
+#define FDS_PAGE_TAG_WORD_0 (0) // Offset of the first word in the page tag from the page address.
+#define FDS_PAGE_TAG_WORD_1 (1) // Offset of the second word in the page tag from the page address.
+
+// Page tag constants
+#define FDS_PAGE_TAG_MAGIC (0xDEADC0DE)
+#define FDS_PAGE_TAG_SWAP (0xF11E01FF)
+#define FDS_PAGE_TAG_DATA (0xF11E01FE)
+
+#define FDS_ERASED_WORD (0xFFFFFFFF)
+
+#define FDS_OFFSET_TL (0) // Offset of TL from the record base address, in 4-byte words.
+#define FDS_OFFSET_IC (1) // Offset of IC from the record base address, in 4-byte words.
+#define FDS_OFFSET_ID (2) // Offset of ID from the record base address, in 4-byte words.
+#define FDS_OFFSET_DATA (3) // Offset of the data 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_IC (1) // Size of the IC part of the header, in 4-byte words.
+#define FDS_HEADER_SIZE_ID (1) // Size of the record ID in the header, in 4-byte words.
+#define FDS_HEADER_SIZE (3) // Size of the whole header, in 4-byte words.
+
+#define FDS_OP_EXECUTING (NRF_SUCCESS)
+#define FDS_OP_COMPLETED (0x1D1D)
+
+#define NRF_FSTORAGE_NVMC 1
+#define NRF_FSTORAGE_SD 2
+
+// The size of a physical page, in 4-byte words.
+#if defined(NRF51)
+ #define FDS_PHY_PAGE_SIZE (256)
+#else
+ #define FDS_PHY_PAGE_SIZE (1024)
+#endif
+
+// The number of physical pages to be used. This value is configured indirectly.
+#define FDS_PHY_PAGES ((FDS_VIRTUAL_PAGES * FDS_VIRTUAL_PAGE_SIZE) / FDS_PHY_PAGE_SIZE)
+
+// The size of a virtual page, in number of physical pages.
+#define FDS_PHY_PAGES_IN_VPAGE (FDS_VIRTUAL_PAGE_SIZE / FDS_PHY_PAGE_SIZE)
+
+// The number of pages available to store data; which is the total minus one (the swap).
+#define FDS_DATA_PAGES (FDS_VIRTUAL_PAGES - 1)
+
+ // Just a shorter name for the size, in words, of a virtual page.
+#define FDS_PAGE_SIZE (FDS_VIRTUAL_PAGE_SIZE)
+
+
+#if (FDS_VIRTUAL_PAGE_SIZE % FDS_PHY_PAGE_SIZE != 0)
+ #error "FDS_VIRTUAL_PAGE_SIZE must be a multiple of the size of a physical page."
+#endif
+
+#if (FDS_VIRTUAL_PAGES < 2)
+ #error "FDS requires at least two virtual pages."
+#endif
+
+
+// Page types.
+typedef enum
+{
+ FDS_PAGE_DATA, // Page is ready for storage.
+ FDS_PAGE_SWAP, // Page is reserved for garbage collection.
+ FDS_PAGE_ERASED, // Page is erased.
+ FDS_PAGE_UNDEFINED, // Undefined page type.
+} fds_page_type_t;
+
+
+typedef enum
+{
+ FDS_HEADER_VALID, // Valid header.
+ FDS_HEADER_DIRTY, // Header is incomplete, or record has been deleted.
+ FDS_HEADER_CORRUPT // Header contains corrupt information, not related to CRC.
+} fds_header_status_t;
+
+
+typedef struct
+{
+ fds_page_type_t page_type; // The page type.
+ uint32_t const * p_addr; // The address of the page.
+ uint16_t write_offset; // The page write offset, in 4-byte words.
+ uint16_t words_reserved; // The amount of words reserved.
+ uint32_t volatile records_open; // The number of open records.
+ bool can_gc; // Indicates that there are some records that have been deleted.
+} fds_page_t;
+
+
+typedef struct
+{
+ uint32_t const * p_addr;
+ uint16_t write_offset;
+} fds_swap_page_t;
+
+
+// FDS op-codes.
+typedef enum
+{
+ FDS_OP_NONE,
+ FDS_OP_INIT, // Initialize the module.
+ FDS_OP_WRITE, // Write a record to flash.
+ FDS_OP_UPDATE, // Update a record.
+ FDS_OP_DEL_RECORD, // Delete a record.
+ FDS_OP_DEL_FILE, // Delete a file.
+ FDS_OP_GC // Run garbage collection.
+} fds_op_code_t;
+
+
+typedef enum
+{
+ FDS_OP_INIT_TAG_SWAP,
+ FDS_OP_INIT_TAG_DATA,
+ FDS_OP_INIT_ERASE_SWAP,
+ FDS_OP_INIT_PROMOTE_SWAP,
+} fds_init_step_t;
+
+
+typedef enum
+{
+ FDS_OP_WRITE_HEADER_BEGIN, // Write the record key and length.
+ FDS_OP_WRITE_HEADER_FINALIZE, // Write the file ID and CRC.
+ FDS_OP_WRITE_RECORD_ID, // Write the record ID.
+ FDS_OP_WRITE_DATA, // Write the record data.
+ FDS_OP_WRITE_FIND_RECORD,
+ FDS_OP_WRITE_FLAG_DIRTY, // Flag a record as dirty (as part of an update operation).
+ FDS_OP_WRITE_DONE,
+} fds_write_step_t;
+
+
+typedef enum
+{
+ FDS_OP_DEL_RECORD_FLAG_DIRTY, // Flag a record as dirty.
+ FDS_OP_DEL_FILE_FLAG_DIRTY, // Flag multiple records as dirty.
+ FDS_OP_DEL_DONE,
+} fds_delete_step_t;
+
+
+#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
+
+typedef struct
+{
+ fds_op_code_t op_code; // The opcode for the operation.
+ union
+ {
+ struct
+ {
+ fds_init_step_t step; // The current step the operation is at.
+ } init;
+ struct
+ {
+ fds_header_t header;
+ void const * p_data;
+ uint16_t page; // The page the flash space for this command was reserved.
+ fds_write_step_t step; // The current step the operation is at.
+ uint32_t record_to_delete; // The record to delete in case this is an update.
+ } write;
+ struct
+ {
+ fds_delete_step_t step;
+ uint16_t file_id;
+ uint16_t record_key;
+ uint32_t record_to_delete;
+ } del;
+ };
+} fds_op_t;
+
+#if defined(__CC_ARM)
+ #pragma pop
+#elif defined(__ICCARM__)
+ // leave anonymous unions enabled
+#elif defined(__GNUC__)
+ // anonymous unions are enabled by default
+#endif
+
+
+enum
+{
+ PAGE_ERASED = 0x1, // One or more erased pages found.
+ PAGE_DATA = 0x2, // One or more data pages found.
+ PAGE_SWAP_CLEAN = 0x4, // A clean (empty) swap page was found.
+ PAGE_SWAP_DIRTY = 0x8, // A dirty (non-empty) swap page was found.
+};
+
+
+typedef enum
+{
+ // No erased pages or FDS pages found.
+ // This is a fatal error.
+ NO_PAGES,
+
+ // The filesystem can not be garbage collected.
+ // This is a fatal error.
+ NO_SWAP = (PAGE_DATA),
+
+ // Perform a fresh installation.
+ FRESH_INSTALL = (PAGE_ERASED),
+
+ // Tag an erased page as swap.
+ TAG_SWAP = (PAGE_ERASED | PAGE_DATA),
+
+ // Tag all erased pages as data.
+ TAG_DATA = (PAGE_ERASED | PAGE_SWAP_CLEAN),
+
+ // Tag all remaining erased pages as data.
+ TAG_DATA_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_CLEAN),
+
+ // The swap is dirty, likely because the device powered off during GC.
+ // Because there is also an erased page, assume that that page has been garbage collected.
+ // Hence, tag the swap as data (promote), an erased page as swap and remaining pages as data.
+ PROMOTE_SWAP = (PAGE_ERASED | PAGE_SWAP_DIRTY),
+
+ // Tag the swap as data (promote), an erased page as swap and remaining pages as data.
+ PROMOTE_SWAP_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_DIRTY),
+
+ // The swap is dirty (written) and there are no erased pages. It is likely that the device
+ // powered off during GC. It is safe to discard (erase) the swap, since data that was
+ // swapped out still lies in one of the valid pages.
+ DISCARD_SWAP = (PAGE_DATA | PAGE_SWAP_DIRTY),
+
+ // Do nothing.
+ ALREADY_INSTALLED = (PAGE_DATA | PAGE_SWAP_CLEAN),
+
+} fds_init_opts_t;
+
+
+typedef enum
+{
+ GC_BEGIN, // Begin GC.
+ GC_NEXT_PAGE, // GC a page.
+ GC_FIND_NEXT_RECORD, // Find a valid record to copy.
+ GC_COPY_RECORD, // Copy a valid record to swap.
+ GC_ERASE_PAGE, // Erase the page being garbage collected.
+ GC_DISCARD_SWAP, // Erase (discard) the swap page.
+ GC_PROMOTE_SWAP, // Tag the swap as valid.
+ GC_TAG_NEW_SWAP // Tag a freshly erased (GCed) page as swap.
+} fds_gc_state_t;
+
+
+// Holds garbage collection status and related data.
+typedef struct
+{
+ fds_gc_state_t state; // The current GC step.
+ uint16_t cur_page; // The current page being garbage collected.
+ uint32_t const * p_record_src; // The current record being copied to swap.
+ uint16_t run_count; // Total number of times GC was run.
+ bool do_gc_page[FDS_DATA_PAGES]; // Controls which pages to garbage collect.
+ bool resume; // Whether or not GC should be resumed.
+} fds_gc_data_t;
+
+
+// Macros to enable and disable application interrupts.
+#if defined (FDS_THREADS)
+
+ #define CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER()
+ #define CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT()
+
+#else
+
+ #define CRITICAL_SECTION_ENTER()
+ #define CRITICAL_SECTION_EXIT()
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FDS_INTERNAL_DEFS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c
new file mode 100644
index 0000000..b14a159
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_FIFO)
+#include "app_fifo.h"
+
+static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo)
+{
+ uint32_t tmp = p_fifo->read_pos;
+ return p_fifo->write_pos - tmp;
+}
+
+
+#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */
+
+
+/**@brief Put one byte to the FIFO. */
+static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte)
+{
+ p_fifo->p_buf[p_fifo->write_pos & p_fifo->buf_size_mask] = byte;
+ p_fifo->write_pos++;
+}
+
+
+/**@brief Look at one byte in the FIFO. */
+static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
+{
+ *p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask];
+}
+
+
+/**@brief Get one byte from the FIFO. */
+static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
+{
+ fifo_peek(p_fifo, 0, p_byte);
+ p_fifo->read_pos++;
+}
+
+
+uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size)
+{
+ // Check buffer for null pointer.
+ if (p_buf == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check that the buffer size is a power of two.
+ if (!IS_POWER_OF_TWO(buf_size))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_fifo->p_buf = p_buf;
+ p_fifo->buf_size_mask = buf_size - 1;
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte)
+{
+ if (FIFO_LENGTH() <= p_fifo->buf_size_mask)
+ {
+ fifo_put(p_fifo, byte);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
+{
+ if (FIFO_LENGTH() != 0)
+ {
+ fifo_get(p_fifo, p_byte);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+
+}
+
+
+uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
+{
+ if (FIFO_LENGTH() > index)
+ {
+ fifo_peek(p_fifo, index, p_byte);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+uint32_t app_fifo_flush(app_fifo_t * p_fifo)
+{
+ p_fifo->read_pos = p_fifo->write_pos;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size)
+{
+ VERIFY_PARAM_NOT_NULL(p_fifo);
+ VERIFY_PARAM_NOT_NULL(p_size);
+
+ const uint32_t byte_count = fifo_length(p_fifo);
+ const uint32_t requested_len = (*p_size);
+ uint32_t index = 0;
+ uint32_t read_size = MIN(requested_len, byte_count);
+
+ (*p_size) = byte_count;
+
+ // Check if the FIFO is empty.
+ if (byte_count == 0)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // Check if application has requested only the size.
+ if (p_byte_array == NULL)
+ {
+ return NRF_SUCCESS;
+ }
+
+ // Fetch bytes from the FIFO.
+ while (index < read_size)
+ {
+ fifo_get(p_fifo, &p_byte_array[index++]);
+ }
+
+ (*p_size) = read_size;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size)
+{
+ VERIFY_PARAM_NOT_NULL(p_fifo);
+ VERIFY_PARAM_NOT_NULL(p_size);
+
+ const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1;
+ const uint32_t requested_len = (*p_size);
+ uint32_t index = 0;
+ uint32_t write_size = MIN(requested_len, available_count);
+
+ (*p_size) = available_count;
+
+ // Check if the FIFO is FULL.
+ if (available_count == 0)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Check if application has requested only the size.
+ if (p_byte_array == NULL)
+ {
+ return NRF_SUCCESS;
+ }
+
+ //Fetch bytes from the FIFO.
+ while (index < write_size)
+ {
+ fifo_put(p_fifo, p_byte_array[index++]);
+ }
+
+ (*p_size) = write_size;
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_FIFO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h
new file mode 100644
index 0000000..8123227
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup app_fifo FIFO implementation
+ * @{
+ * @ingroup app_common
+ *
+ * @brief FIFO implementation.
+ */
+
+#ifndef APP_FIFO_H__
+#define APP_FIFO_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A FIFO instance structure.
+ * @details Keeps track of which bytes to read and write next.
+ * Also, it keeps the information about which memory is allocated for the buffer
+ * and its size. This structure must be initialized by app_fifo_init() before use.
+ */
+typedef struct
+{
+ uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */
+ uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */
+ volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
+ volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
+} app_fifo_t;
+
+/**@brief Function for initializing the FIFO.
+ *
+ * @param[out] p_fifo FIFO object.
+ * @param[in] p_buf FIFO buffer for storing data. The buffer size must be a power of two.
+ * @param[in] buf_size Size of the FIFO buffer provided. This size must be a power of two.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer.
+ * @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is not a power of two.
+ */
+uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size);
+
+/**@brief Function for adding an element to the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ * @param[in] byte Data byte to add to the FIFO.
+ *
+ * @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
+ * @retval NRF_ERROR_NO_MEM If the FIFO is full.
+ */
+uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte);
+
+/**@brief Function for getting the next element from the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ * @param[out] p_byte Byte fetched from the FIFO.
+ *
+ * @retval NRF_SUCCESS If an element was returned.
+ * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte);
+
+/**@brief Function for looking at an element in the FIFO, without consuming it.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ * @param[in] index Which element to look at. The lower the index, the earlier it was put.
+ * @param[out] p_byte Byte fetched from the FIFO.
+ *
+ * @retval NRF_SUCCESS If an element was returned.
+ * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue, or the index was
+ * too large.
+ */
+uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte);
+
+/**@brief Function for flushing the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ *
+ * @retval NRF_SUCCESS If the FIFO was flushed successfully.
+ */
+uint32_t app_fifo_flush(app_fifo_t * p_fifo);
+
+/**@brief Function for reading bytes from the FIFO.
+ *
+ * This function can also be used to get the number of bytes in the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
+ * @param[out] p_byte_array Memory pointer where the read bytes are fetched from the FIFO.
+ * Can be NULL. If NULL, the number of bytes that can be read in the FIFO
+ * are returned in the p_size parameter.
+ * @param[inout] p_size Address to memory indicating the maximum number of bytes to be read.
+ * The provided memory is overwritten with the actual number of bytes
+ * read if the procedure was successful. This field must not be NULL.
+ * If p_byte_array is set to NULL by the application, this parameter
+ * returns the number of bytes in the FIFO.
+ *
+ * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes read might
+ * be less than the requested maximum, depending on how many elements exist
+ * in the FIFO. Even if less bytes are returned, the procedure is considered
+ * successful.
+ * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
+ * be NULL.
+ * @retval NRF_ERROR_NOT_FOUND If the FIFO is empty.
+ */
+uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size);
+
+/**@brief Function for writing bytes to the FIFO.
+ *
+ * This function can also be used to get the available size on the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
+ * @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO.
+ * Can be NULL. If NULL, this function returns the number of bytes
+ * that can be written to the FIFO.
+ * @param[inout] p_size Address to memory indicating the maximum number of bytes to be written.
+ * The provided memory is overwritten with the number of bytes that were actually
+ * written if the procedure is successful. This field must not be NULL.
+ * If p_byte_array is set to NULL by the application, this parameter
+ * returns the number of bytes available in the FIFO.
+ *
+ * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes written might
+ * be less than the requested maximum, depending on how much room there is in
+ * the FIFO. Even if less bytes are written, the procedure is considered
+ * successful. If the write was partial, the application should use
+ * subsequent calls to attempt writing the data again.
+ * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
+ * be NULL.
+ * @retval NRF_ERROR_NO_MEM If the FIFO is full.
+ *
+ */
+uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_FIFO_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c
new file mode 100644
index 0000000..d96abce
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+
+#if NRF_FSTORAGE_ENABLED
+
+#include "nrf_fstorage.h"
+#include <stddef.h>
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "sdk_macros.h"
+#include "nrf_section.h"
+
+#define NRF_LOG_MODULE_NAME nrf_fstorage
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/* Create the section "fs_data". */
+NRF_SECTION_DEF(fs_data, nrf_fstorage_t);
+
+
+/**@brief Macro to handle user input validation.
+ *
+ * If @p _cond evaluates to true, does nothing. Otherwise,
+ * if the NRF_FSTORAGE_PARAM_CHECK_DISABLED is not set, logs an error message and returns @p _err.
+ * If the NRF_FSTORAGE_PARAM_CHECK_DISABLED is set, behaves like the @ref ASSERT macro.
+ *
+ * Parameter checking implemented using this macro can be optionally turned off for release code.
+ * Only disable runtime parameter checks if size if a major concern.
+ *
+ * @param _cond The condition to be evaluated.
+ * @param _err The error code to be returned.
+ */
+#define NRF_FSTORAGE_PARAM_CHECK(_cond, _err) \
+ NRF_PARAM_CHECK(NRF_FSTORAGE, _cond, _err, NRF_LOG_ERROR)
+
+
+static bool addr_is_aligned32(uint32_t addr);
+static bool addr_is_page_aligned(nrf_fstorage_t const * p_fs, uint32_t addr);
+static bool addr_is_within_bounds(nrf_fstorage_t const * p_fs, uint32_t addr, uint32_t len);
+
+
+ret_code_t nrf_fstorage_init(nrf_fstorage_t * p_fs,
+ nrf_fstorage_api_t * p_api,
+ void * p_param)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_api, NRF_ERROR_NULL);
+
+ p_fs->p_api = p_api;
+
+ return (p_fs->p_api)->init(p_fs, p_param);
+}
+
+
+ret_code_t nrf_fstorage_uninit(nrf_fstorage_t * p_fs,
+ void * p_param)
+{
+ ret_code_t rc;
+
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+
+ rc = (p_fs->p_api)->uninit(p_fs, p_param);
+
+ /* Uninitialize the API. */
+ p_fs->p_api = NULL;
+ p_fs->p_flash_info = NULL;
+
+ return rc;
+}
+
+
+ret_code_t nrf_fstorage_read(nrf_fstorage_t const * p_fs,
+ uint32_t src,
+ void * p_dest,
+ uint32_t len)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_dest, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+ NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH);
+
+ /* Source addres must be word-aligned. */
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32(src), NRF_ERROR_INVALID_ADDR);
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_within_bounds(p_fs, src, len), NRF_ERROR_INVALID_ADDR);
+
+ return (p_fs->p_api)->read(p_fs, src, p_dest, len);
+}
+
+
+ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_context)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_src, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+ NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH);
+
+ /* Length must be a multiple of the program unit. */
+ NRF_FSTORAGE_PARAM_CHECK(!(len % p_fs->p_flash_info->program_unit), NRF_ERROR_INVALID_LENGTH);
+
+ /* Source and destination addresses must be word-aligned. */
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32(dest), NRF_ERROR_INVALID_ADDR);
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32((uint32_t)p_src), NRF_ERROR_INVALID_ADDR);
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_within_bounds(p_fs, dest, len), NRF_ERROR_INVALID_ADDR);
+
+ return (p_fs->p_api)->write(p_fs, dest, p_src, len, p_context);
+}
+
+
+ret_code_t nrf_fstorage_erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_context)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+ NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH);
+
+ /* Address must be aligned to a page boundary. */
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_page_aligned(p_fs, page_addr), NRF_ERROR_INVALID_ADDR);
+
+ NRF_FSTORAGE_PARAM_CHECK(
+ addr_is_within_bounds(p_fs, page_addr, (len * p_fs->p_flash_info->erase_unit)),
+ NRF_ERROR_INVALID_ADDR
+ );
+
+ return (p_fs->p_api)->erase(p_fs, page_addr, len, p_context);
+}
+
+
+uint8_t const * nrf_fstorage_rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ if ((p_fs == NULL) || (p_fs->p_api == NULL))
+ {
+ return NULL;
+ }
+
+ return (p_fs->p_api)->rmap(p_fs, addr);
+}
+
+
+uint8_t * nrf_fstorage_wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ if ((p_fs == NULL) || (p_fs->p_api == NULL))
+ {
+ return NULL;
+ }
+
+ return (p_fs->p_api)->wmap(p_fs, addr);
+}
+
+
+bool nrf_fstorage_is_busy(nrf_fstorage_t const * p_fs)
+{
+ /* If a NULL instance is provided, return true if any instance is busy.
+ * Uninitialized instances are considered not busy. */
+ if ((p_fs == NULL) || (p_fs->p_api == NULL))
+ {
+ for (uint32_t i = 0; i < NRF_FSTORAGE_INSTANCE_CNT; i++)
+ {
+ p_fs = NRF_FSTORAGE_INSTANCE_GET(i); /* cannot be NULL. */
+ if (p_fs->p_api != NULL)
+ {
+ /* p_api->is_busy() cannot be NULL. */
+ if (p_fs->p_api->is_busy(p_fs))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ return p_fs->p_api->is_busy(p_fs);
+}
+
+
+static bool addr_is_within_bounds(nrf_fstorage_t const * p_fs,
+ uint32_t addr,
+ uint32_t len)
+{
+ return ( (addr >= p_fs->start_addr)
+ && (addr + len - 1 <= p_fs->end_addr));
+}
+
+
+static bool addr_is_aligned32(uint32_t addr)
+{
+ return !(addr & 0x03);
+}
+
+
+static bool addr_is_page_aligned(nrf_fstorage_t const * p_fs,
+ uint32_t addr)
+{
+ return (addr & (p_fs->p_flash_info->erase_unit - 1)) == 0;
+}
+
+
+#endif // NRF_FSTORAGE_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h
new file mode 100644
index 0000000..b678950
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h
@@ -0,0 +1,341 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_FSTORAGE_H__
+#define NRF_FSTORAGE_H__
+
+/**
+ * @file
+ *
+ * @defgroup nrf_fstorage Flash storage (fstorage)
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Flash abstraction library that provides basic read, write, and erase operations.
+ *
+ * @details The fstorage library can be implemented in different ways. Two implementations are provided:
+ * - The @ref nrf_fstorage_sd implements flash access through the SoftDevice.
+ * - The @ref nrf_fstorage_nvmc implements flash access through the non-volatile memory controller.
+ *
+ * You can select the implementation that should be used independently for each instance of fstorage.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "nrf_section.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Macro for defining an fstorage instance.
+ *
+ * Users of fstorage must define an instance variable by using this macro.
+ * Each instance is tied to an API implementation and contains information such
+ * as the program and erase units for the target flash peripheral.
+ * Instance variables are placed in the "fs_data" section of the binary.
+ *
+ * @param[in] inst A definition of an @ref nrf_fstorage_t variable.
+ */
+#define NRF_FSTORAGE_DEF(inst) NRF_SECTION_ITEM_REGISTER(fs_data, inst)
+
+/**@brief Macro for retrieving an fstorage instance. */
+#define NRF_FSTORAGE_INSTANCE_GET(i) NRF_SECTION_ITEM_GET(fs_data, nrf_fstorage_t, (i))
+
+/**@brief Macro for retrieving the total number of fstorage instances. */
+#define NRF_FSTORAGE_INSTANCE_CNT NRF_SECTION_ITEM_COUNT(fs_data, nrf_fstorage_t)
+
+
+/**@brief Event IDs. */
+typedef enum
+{
+ NRF_FSTORAGE_EVT_READ_RESULT,
+ NRF_FSTORAGE_EVT_WRITE_RESULT, //!< Event for @ref nrf_fstorage_write.
+ NRF_FSTORAGE_EVT_ERASE_RESULT //!< Event for @ref nrf_fstorage_erase.
+} nrf_fstorage_evt_id_t;
+
+
+/**@brief An fstorage event. */
+typedef struct
+{
+ nrf_fstorage_evt_id_t id; //!< The event ID.
+ ret_code_t result; //!< Result of the operation.
+ uint32_t addr; //!< Address at which the operation was performed.
+ void const * p_src; //!< Buffer written to flash.
+ uint32_t len; //!< Length of the operation.
+ void * p_param; //!< User-defined parameter passed to the event handler.
+} nrf_fstorage_evt_t;
+
+
+/**@brief Event handler function prototype.
+ *
+ * @param[in] p_evt The event.
+ */
+typedef void (*nrf_fstorage_evt_handler_t)(nrf_fstorage_evt_t * p_evt);
+
+
+/**@brief Information about the implementation and the flash peripheral. */
+typedef struct
+{
+ uint32_t erase_unit; //!< Size of a flash page (in bytes). A flash page is the smallest unit that can be erased.
+ uint32_t program_unit; //!< Size of the smallest programmable unit (in bytes).
+ bool rmap; //!< The device address space is memory mapped to the MCU address space.
+ bool wmap; //!< The device address space is memory mapped to a writable MCU address space.
+} const nrf_fstorage_info_t;
+
+
+/* Necessary forward declaration. */
+struct nrf_fstorage_api_s;
+
+
+/**@brief An fstorage instance.
+ *
+ * @details Use the @ref NRF_FSTORAGE_DEF macro to define an fstorage instance.
+ *
+ * An instance is tied to an API implementation and contains information about the flash device,
+ * such as the program and erase units as well and implementation-specific functionality.
+ */
+typedef struct
+{
+ /**@brief The API implementation used by this instance. */
+ struct nrf_fstorage_api_s const * p_api;
+
+ /**@brief Information about the implementation functionality and the flash peripheral. */
+ nrf_fstorage_info_t * p_flash_info;
+
+ /**@brief The event handler function.
+ *
+ * If set to NULL, no events will be sent.
+ */
+ nrf_fstorage_evt_handler_t evt_handler;
+
+ /**@brief The beginning of the flash space on which this fstorage instance should operate.
+ * All flash operations must be within the address specified in
+ * this field and @ref end_addr.
+ *
+ * This field must be set manually.
+ */
+ uint32_t start_addr;
+
+ /**@brief The last address (exclusive) of flash on which this fstorage instance should operate.
+ * All flash operations must be within the address specified in
+ * this field and @ref start_addr.
+ *
+ * This field must be set manually.
+ */
+ uint32_t end_addr;
+} nrf_fstorage_t;
+
+
+/**@brief Functions provided by the API implementation. */
+typedef struct nrf_fstorage_api_s
+{
+ /**@brief Initialize the flash peripheral. */
+ ret_code_t (*init)(nrf_fstorage_t * p_fs, void * p_param);
+ /**@brief Uninitialize the flash peripheral. */
+ ret_code_t (*uninit)(nrf_fstorage_t * p_fs, void * p_param);
+ /**@brief Read data from flash. */
+ ret_code_t (*read)(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len);
+ /**@brief Write bytes to flash. */
+ ret_code_t (*write)(nrf_fstorage_t const * p_fs, uint32_t dest, void const * p_src, uint32_t len, void * p_param);
+ /**@brief Erase flash pages. */
+ ret_code_t (*erase)(nrf_fstorage_t const * p_fs, uint32_t addr, uint32_t len, void * p_param);
+ /**@brief Map a device address to a readable address within the MCU address space. */
+ uint8_t const * (*rmap)(nrf_fstorage_t const * p_fs, uint32_t addr);
+ /**@brief Map a device address to a writable address within the MCU address space. */
+ uint8_t * (*wmap)(nrf_fstorage_t const * p_fs, uint32_t addr);
+ /**@brief Check if there are any pending flash operations. */
+ bool (*is_busy)(nrf_fstorage_t const * p_fs);
+} const nrf_fstorage_api_t;
+
+
+/**@brief Function for initializing fstorage.
+ *
+ * @param[in] p_fs The fstorage instance to initialize.
+ * @param[in] p_api The API implementation to use.
+ * @param[in] p_param An optional parameter to pass to the implementation-specific API call.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If @p p_fs or @p p_api field in @p p_fs is NULL.
+ * @retval NRF_ERROR_INTERNAL If another error occurred.
+ */
+ret_code_t nrf_fstorage_init(nrf_fstorage_t * p_fs,
+ nrf_fstorage_api_t * p_api,
+ void * p_param);
+
+
+/**@brief Function for uninitializing an fstorage instance.
+ *
+ * @param[in] p_fs The fstorage instance to uninitialize.
+ * @param[in] p_param An optional parameter to pass to the implementation-specific API call.
+ *
+ * @retval NRF_SUCCESS If uninitialization was successful.
+ * @retval NRF_ERROR_NULL If @p p_fs is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INTERNAL If another error occurred.
+ */
+ret_code_t nrf_fstorage_uninit(nrf_fstorage_t * p_fs, void * p_param);
+
+
+/**@brief Function for reading data from flash.
+ *
+ * Copy @p len bytes from @p addr to @p p_dest.
+ *
+ * @param[in] p_fs The fstorage instance.
+ * @param[in] addr Address in flash where to read from.
+ * @param[in] p_dest Buffer where the data should be copied.
+ * @param[in] len Length of the data to be copied (in bytes).
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_fs or @p p_dest is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero or otherwise invalid.
+ * @retval NRF_ERROR_INVALID_ADDR If the address @p addr is outside the flash memory
+ * boundaries specified in @p p_fs, or if it is unaligned.
+ */
+ret_code_t nrf_fstorage_read(nrf_fstorage_t const * p_fs,
+ uint32_t addr,
+ void * p_dest,
+ uint32_t len);
+
+
+/**@brief Function for writing data to flash.
+ *
+ * Write @p len bytes from @p p_src to @p dest.
+ *
+ * When using @ref nrf_fstorage_sd, the data is written by several calls to @ref sd_flash_write if
+ * the length of the data exceeds @ref NRF_FSTORAGE_SD_MAX_WRITE_SIZE bytes.
+ * Only one event is sent upon completion.
+ *
+ * @note The data to be written to flash must be kept in memory until the operation has
+ * terminated and an event is received.
+ *
+ * @param[in] p_fs The fstorage instance.
+ * @param[in] dest Address in flash memory where to write the data.
+ * @param[in] p_src Data to be written.
+ * @param[in] len Length of the data (in bytes).
+ * @param[in] p_param User-defined parameter passed to the event handler (may be NULL).
+ *
+ * @retval NRF_SUCCESS If the operation was accepted.
+ * @retval NRF_ERROR_NULL If @p p_fs or @p p_src is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero or not a multiple of the program unit,
+ * or if it is otherwise invalid.
+ * @retval NRF_ERROR_INVALID_ADDR If the address @p dest is outside the flash memory
+ * boundaries specified in @p p_fs, or if it is unaligned.
+ * @retval NRF_ERROR_NO_MEM If no memory is available to accept the operation.
+ * When using the @ref nrf_fstorage_sd, this error
+ * indicates that the internal queue of operations is full.
+ */
+ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_param);
+
+
+/**@brief Function for erasing flash pages.
+ *
+ * @details This function erases @p len pages starting from the page at address @p page_addr.
+ * The erase operation must be initiated on a page boundary.
+ *
+ * @param[in] p_fs The fstorage instance.
+ * @param[in] page_addr Address of the page to erase.
+ * @param[in] len Number of pages to erase.
+ * @param[in] p_param User-defined parameter passed to the event handler (may be NULL).
+ *
+ * @retval NRF_SUCCESS If the operation was accepted.
+ * @retval NRF_ERROR_NULL If @p p_fs is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero.
+ * @retval NRF_ERROR_INVALID_ADDR If the address @p page_addr is outside the flash memory
+ * boundaries specified in @p p_fs, or if it is unaligned.
+ * @retval NRF_ERROR_NO_MEM If no memory is available to accept the operation.
+ * When using the @ref nrf_fstorage_sd, this error
+ * indicates that the internal queue of operations is full.
+ */
+ret_code_t nrf_fstorage_erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_param);
+
+
+/**@brief Map a flash address to a pointer in the MCU address space that can be dereferenced.
+ *
+ * @param p_fs The fstorage instance.
+ * @param addr The address to map.
+ *
+ * @retval A pointer to the specified address,
+ * or @c NULL if the address cannot be mapped or if @p p_fs is @c NULL.
+ */
+uint8_t const * nrf_fstorage_rmap(nrf_fstorage_t const * p_fs, uint32_t addr);
+
+
+/**@brief Map a flash address to a pointer in the MCU address space that can be written to.
+ *
+ * @param p_fs The fstorage instance.
+ * @param addr The address to map.
+ *
+ * @retval A pointer to the specified address,
+ * or @c NULL if the address cannot be mapped or if @p p_fs is @c NULL.
+ */
+uint8_t * nrf_fstorage_wmap(nrf_fstorage_t const * p_fs, uint32_t addr);
+
+
+/**@brief Function for querying the status of fstorage.
+ *
+ * @details An uninitialized instance of fstorage is treated as not busy.
+ *
+ * @param[in] p_fs The fstorage instance. Pass NULL to query all instances.
+ *
+ * @returns If @p p_fs is @c NULL, this function returns true if any fstorage instance is busy or false otherwise.
+ * @returns If @p p_fs is not @c NULL, this function returns true if the fstorage instance is busy or false otherwise.
+ */
+ bool nrf_fstorage_is_busy(nrf_fstorage_t const * p_fs);
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FSTORAGE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c
new file mode 100644
index 0000000..14b1859
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c
@@ -0,0 +1,217 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_FSTORAGE)
+
+#include "nrf_fstorage_nvmc.h"
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nrf_nvmc.h"
+#include "nrf_atomic.h"
+
+
+static nrf_fstorage_info_t m_flash_info =
+{
+#if defined(NRF51)
+ .erase_unit = 1024,
+#elif defined(NRF52_SERIES)
+ .erase_unit = 4096,
+#endif
+ .program_unit = 4,
+ .rmap = true,
+ .wmap = false,
+};
+
+
+ /* An operation initiated by fstorage is ongoing. */
+static nrf_atomic_flag_t m_flash_operation_ongoing;
+
+
+/* Send event to the event handler. */
+static void event_send(nrf_fstorage_t const * p_fs,
+ nrf_fstorage_evt_id_t evt_id,
+ void const * p_src,
+ uint32_t addr,
+ uint32_t len,
+ void * p_param)
+{
+ if (p_fs->evt_handler == NULL)
+ {
+ /* Nothing to do. */
+ return;
+ }
+
+ nrf_fstorage_evt_t evt =
+ {
+ .result = NRF_SUCCESS,
+ .id = evt_id,
+ .addr = addr,
+ .p_src = p_src,
+ .len = len,
+ .p_param = p_param,
+ };
+
+ p_fs->evt_handler(&evt);
+}
+
+
+static ret_code_t init(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_param);
+
+ p_fs->p_flash_info = &m_flash_info;
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t uninit(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(p_param);
+
+ (void) nrf_atomic_flag_clear(&m_flash_operation_ongoing);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t read(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ memcpy(p_dest, (uint32_t*)src, len);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_param)
+{
+ if (nrf_atomic_flag_set_fetch(&m_flash_operation_ongoing))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_nvmc_write_words(dest, (uint32_t*)p_src, (len / m_flash_info.program_unit));
+
+ /* Clear the flag before sending the event, to allow API calls in the event context. */
+ (void) nrf_atomic_flag_clear(&m_flash_operation_ongoing);
+
+ event_send(p_fs, NRF_FSTORAGE_EVT_WRITE_RESULT, p_src, dest, len, p_param);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_param)
+{
+ uint32_t progress = 0;
+
+ if (nrf_atomic_flag_set_fetch(&m_flash_operation_ongoing))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ while (progress != len)
+ {
+ nrf_nvmc_page_erase(page_addr + (progress * m_flash_info.erase_unit));
+ progress++;
+ }
+
+ /* Clear the flag before sending the event, to allow API calls in the event context. */
+ (void) nrf_atomic_flag_clear(&m_flash_operation_ongoing);
+
+ event_send(p_fs, NRF_FSTORAGE_EVT_ERASE_RESULT, NULL, page_addr, len, p_param);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint8_t const * rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return (uint8_t*)addr;
+}
+
+
+static uint8_t * wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(addr);
+
+ /* Not supported. */
+ return NULL;
+}
+
+
+static bool is_busy(nrf_fstorage_t const * p_fs)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return m_flash_operation_ongoing;
+}
+
+
+/* The exported API. */
+nrf_fstorage_api_t nrf_fstorage_nvmc =
+{
+ .init = init,
+ .uninit = uninit,
+ .read = read,
+ .write = write,
+ .erase = erase,
+ .rmap = rmap,
+ .wmap = wmap,
+ .is_busy = is_busy
+};
+
+
+#endif // NRF_FSTORAGE_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h
new file mode 100644
index 0000000..bacd745
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ *
+ * @defgroup nrf_fstorage_nvmc NVMC implementation
+ * @ingroup nrf_fstorage
+ * @{
+ *
+ * @brief API implementation of fstorage that uses the non-volatile memory controller (NVMC).
+*/
+
+#ifndef NRF_FSTORAGE_NVMC_H__
+#define NRF_FSTORAGE_NVMC_H__
+
+#include "nrf_fstorage.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief API implementation that uses the non-volatile memory controller.
+ *
+ * @details An fstorage instance with this API implementation can be initialized by providing
+ * this structure as a parameter to @ref nrf_fstorage_init.
+ * The structure is defined in @c nrf_fstorage_nvmc.c.
+ */
+extern nrf_fstorage_api_t nrf_fstorage_nvmc;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FSTORAGE_NVMC_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c
new file mode 100644
index 0000000..ef5f6b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c
@@ -0,0 +1,624 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_FSTORAGE)
+
+#include "nrf_fstorage_sd.h"
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nordic_common.h"
+#include "nrf_soc.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_soc.h"
+#include "nrf_atomic.h"
+#include "nrf_atfifo.h"
+#include "app_util_platform.h"
+
+
+#if (NRF_FSTORAGE_SD_MAX_WRITE_SIZE % 4)
+#error NRF_FSTORAGE_SD_MAX_WRITE_SIZE must be a multiple of the word size.
+#endif
+
+
+/**@brief fstorage operation codes. */
+typedef enum
+{
+ NRF_FSTORAGE_OP_WRITE, //!< Write bytes to flash.
+ NRF_FSTORAGE_OP_ERASE //!< Erase flash pages.
+} nrf_fstorage_sd_opcode_t;
+
+ANON_UNIONS_ENABLE;
+/**@brief fstorage operation queue element. */
+typedef struct
+{
+ nrf_fstorage_t const * p_fs; //!< The fstorage instance that requested the operation.
+ nrf_fstorage_sd_opcode_t op_code; //!< Requested operation.
+ void * p_param; //!< User-defined parameter passed to the event handler.
+ union
+ {
+ struct
+ {
+ void const * p_src; //!< Data to be written to flash.
+ uint32_t dest; //!< Destination of the data in flash.
+ uint32_t len; //!< Length of the data to be written (in bytes).
+ uint32_t offset; //!< Write offset.
+ } write;
+ struct
+ {
+ uint32_t page; //!< Physical page number.
+ uint32_t progress; //!< Number of pages erased.
+ uint32_t pages_to_erase; //!< Total number of pages to erase.
+ } erase;
+ };
+} nrf_fstorage_sd_op_t;
+ANON_UNIONS_DISABLE;
+
+typedef enum
+{
+ NRF_FSTORAGE_STATE_IDLE, //!< No operations requested to the SoftDevice.
+ NRF_FSTORAGE_STATE_OP_PENDING, //!< A non-fstorage operation is pending.
+ NRF_FSTORAGE_STATE_OP_EXECUTING, //!< An fstorage operation is executing.
+} nrf_fstorage_sd_state_t;
+
+/**@brief Internal state. */
+typedef struct
+{
+ nrf_atomic_flag_t initialized; //!< fstorage is initalized.
+ nrf_atomic_flag_t queue_running; //!< The queue is running.
+ /** Prevent API calls from entering queue_process(). */
+ nrf_fstorage_sd_state_t state; //!< Internal fstorage state.
+ uint32_t retries; //!< Number of times an operation has been retried on timeout.
+ bool sd_enabled; //!< The SoftDevice is enabled.
+ bool paused; //!< A SoftDevice state change is impending.
+ /** Do not load a new operation when the last one completes. */
+} nrf_fstorage_sd_work_t;
+
+
+void nrf_fstorage_sys_evt_handler(uint32_t, void *);
+bool nrf_fstorage_sdh_req_handler(nrf_sdh_req_evt_t, void *);
+void nrf_fstorage_sdh_state_handler(nrf_sdh_state_evt_t, void *);
+
+
+/* Flash device information. */
+static nrf_fstorage_info_t m_flash_info =
+{
+#if defined(NRF51)
+ .erase_unit = 1024,
+#elif defined(NRF52_SERIES)
+ .erase_unit = 4096,
+#endif
+ .program_unit = 4,
+ .rmap = true,
+ .wmap = false,
+};
+
+/* Queue of fstorage operations. */
+NRF_ATFIFO_DEF(m_fifo, nrf_fstorage_sd_op_t, NRF_FSTORAGE_SD_QUEUE_SIZE);
+
+/* Define a nrf_sdh_soc event observer to receive SoftDevice system events. */
+NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, nrf_fstorage_sys_evt_handler, NULL);
+
+/* nrf_sdh request observer. */
+NRF_SDH_REQUEST_OBSERVER(m_req_obs, 0) =
+{
+ .handler = nrf_fstorage_sdh_req_handler,
+};
+
+/* nrf_sdh state observer. */
+NRF_SDH_STATE_OBSERVER(m_state_obs, 0) =
+{
+ .handler = nrf_fstorage_sdh_state_handler,
+};
+
+static nrf_fstorage_sd_work_t m_flags; /* Internal status. */
+static nrf_fstorage_sd_op_t * m_p_cur_op; /* The current operation being executed. */
+static nrf_atfifo_item_get_t m_iget_ctx; /* Context for nrf_atfifo_item_get() and nrf_atfifo_item_free(). */
+
+
+/* Send events to the application. */
+static void event_send(nrf_fstorage_sd_op_t const * p_op, ret_code_t result)
+{
+ if (p_op->p_fs->evt_handler == NULL)
+ {
+ /* Nothing to do. */
+ return;
+ }
+
+ nrf_fstorage_evt_t evt =
+ {
+ .result = result,
+ .p_param = p_op->p_param,
+ };
+
+ switch (p_op->op_code)
+ {
+ case NRF_FSTORAGE_OP_WRITE:
+ evt.id = NRF_FSTORAGE_EVT_WRITE_RESULT;
+ evt.addr = p_op->write.dest;
+ evt.p_src = p_op->write.p_src;
+ evt.len = p_op->write.len;
+ break;
+
+ case NRF_FSTORAGE_OP_ERASE:
+ evt.id = NRF_FSTORAGE_EVT_ERASE_RESULT;
+ evt.addr = (p_op->erase.page * m_flash_info.erase_unit);
+ evt.len = p_op->erase.pages_to_erase;
+ break;
+
+ default:
+ /* Should not happen. */
+ break;
+ }
+
+ p_op->p_fs->evt_handler(&evt);
+}
+
+
+/* Write to flash. */
+static uint32_t write_execute(nrf_fstorage_sd_op_t const * p_op)
+{
+ uint32_t chunk_len;
+
+ chunk_len = MIN(p_op->write.len - p_op->write.offset, NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
+ chunk_len = MAX(1, chunk_len / m_flash_info.program_unit);
+
+ /* Cast to p_src to uint32_t to perform arithmetic. */
+ uint32_t * p_dest = (uint32_t*)(p_op->write.dest + p_op->write.offset);
+ uint32_t const * p_src = (uint32_t*)((uint32_t)p_op->write.p_src + p_op->write.offset);
+
+ return sd_flash_write(p_dest, p_src, chunk_len);
+}
+
+
+/* Erase flash page(s). */
+static uint32_t erase_execute(nrf_fstorage_sd_op_t const * p_op)
+{
+ return sd_flash_page_erase(p_op->erase.page + p_op->erase.progress);
+}
+
+
+/* Free the current queue element. */
+static void queue_free(void)
+{
+ (void) nrf_atfifo_item_free(m_fifo, &m_iget_ctx);
+}
+
+
+/* Load a new operation from the queue. */
+static bool queue_load_next(void)
+{
+ m_p_cur_op = nrf_atfifo_item_get(m_fifo, &m_iget_ctx);
+
+ return (m_p_cur_op != NULL);
+}
+
+
+/* Execute an operation in the queue. */
+static void queue_process(void)
+{
+ uint32_t rc;
+
+ if (m_flags.state == NRF_FSTORAGE_STATE_IDLE)
+ {
+ if (!queue_load_next())
+ {
+ /* No more operations, nothing to do. */
+ m_flags.queue_running = false;
+ return;
+ }
+ }
+
+ m_flags.state = NRF_FSTORAGE_STATE_OP_EXECUTING;
+
+ switch (m_p_cur_op->op_code)
+ {
+ case NRF_FSTORAGE_OP_WRITE:
+ rc = write_execute(m_p_cur_op);
+ break;
+
+ case NRF_FSTORAGE_OP_ERASE:
+ rc = erase_execute(m_p_cur_op);
+ break;
+
+ default:
+ rc = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ switch (rc)
+ {
+ case NRF_SUCCESS:
+ {
+ /* The operation was accepted by the SoftDevice.
+ * If the SoftDevice is enabled, wait for a system event. Otherwise,
+ * the SoftDevice call is synchronous and will not send an event so we simulate it. */
+ if (!m_flags.sd_enabled)
+ {
+ nrf_fstorage_sys_evt_handler(NRF_EVT_FLASH_OPERATION_SUCCESS, NULL);
+ }
+ } break;
+
+ case NRF_ERROR_BUSY:
+ {
+ /* The SoftDevice is executing a flash operation that was not requested by fstorage.
+ * Stop processing the queue until a system event is received. */
+ m_flags.state = NRF_FSTORAGE_STATE_OP_PENDING;
+ } break;
+
+ default:
+ {
+ /* An error has occurred. We cannot proceed further with this operation. */
+ event_send(m_p_cur_op, NRF_ERROR_INTERNAL);
+ /* Reset the internal state so we can accept other operations. */
+ m_flags.state = NRF_FSTORAGE_STATE_IDLE;
+ m_flags.queue_running = false;
+ /* Free the current queue element. */
+ queue_free();
+ } break;
+ }
+}
+
+
+/* Start processing the queue if it is not running and fstorage is not paused. */
+static void queue_start(void)
+{
+ if ( (!nrf_atomic_flag_set_fetch(&m_flags.queue_running))
+ && (!m_flags.paused))
+ {
+ queue_process();
+ }
+}
+
+
+/* Flash operation success callback. Keeps track of the progress of an operation. */
+static bool on_operation_success(nrf_fstorage_sd_op_t * const p_op)
+{
+ /* Reset the retry counter on success. */
+ m_flags.retries = 0;
+
+ switch (p_op->op_code)
+ {
+ case NRF_FSTORAGE_OP_WRITE:
+ {
+ /* Update the offset only if the operation is successful
+ * so that it can be retried in case it times out. */
+ uint32_t const chunk_len = MIN(p_op->write.len - p_op->write.offset,
+ NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
+
+ p_op->write.offset += chunk_len;
+
+ if (p_op->write.offset == p_op->write.len)
+ {
+ return true;
+ }
+ } break;
+
+ case NRF_FSTORAGE_OP_ERASE:
+ {
+ p_op->erase.progress++;
+
+ if (p_op->erase.progress == p_op->erase.pages_to_erase)
+ {
+ return true;
+ }
+ } break;
+
+ default:
+ /* Should not happen. */
+ break;
+ }
+
+ return false;
+}
+
+
+/* Flash operation failure callback. */
+static bool on_operation_failure(nrf_fstorage_sd_op_t const * p_op)
+{
+ UNUSED_PARAMETER(p_op);
+
+ m_flags.retries++;
+
+ if (m_flags.retries > NRF_FSTORAGE_SD_MAX_RETRIES)
+ {
+ /* Maximum amount of retries reached. Give up. */
+ m_flags.retries = 0;
+ return true;
+ }
+
+ return false;
+}
+
+
+static ret_code_t init(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_param);
+
+ p_fs->p_flash_info = &m_flash_info;
+
+ if (!nrf_atomic_flag_set_fetch(&m_flags.initialized))
+ {
+#if NRF_SDH_ENABLED
+ m_flags.sd_enabled = nrf_sdh_is_enabled();
+#endif
+ (void) NRF_ATFIFO_INIT(m_fifo);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t uninit(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(p_param);
+
+ /* The state is re-initialized upon init().
+ * The common uninitialization code is run by the caller. */
+
+ memset(&m_flags, 0x00, sizeof(m_flags));
+
+ (void) nrf_atfifo_clear(m_fifo);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_param)
+{
+ nrf_fstorage_sd_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ /* Get a free queue element. */
+ p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
+
+ if (p_op == NULL)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Initialize the operation. */
+ memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
+
+ p_op->op_code = NRF_FSTORAGE_OP_WRITE;
+ p_op->p_fs = p_fs;
+ p_op->p_param = p_param;
+ p_op->write.dest = dest;
+ p_op->write.p_src = p_src;
+ p_op->write.len = len;
+
+ /* Put the operation on the queue. */
+ (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
+
+ queue_start();
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t read(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len)
+{
+ memcpy(p_dest, (uint32_t*)src, len);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_param)
+{
+ nrf_fstorage_sd_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ /* Get a free queue element. */
+ p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
+
+ if (p_op == NULL)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Initialize the operation. */
+ memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
+
+ p_op->op_code = NRF_FSTORAGE_OP_ERASE;
+ p_op->p_fs = p_fs;
+ p_op->p_param = p_param;
+ p_op->erase.page = (page_addr / m_flash_info.erase_unit);
+ p_op->erase.pages_to_erase = len;
+
+ /* Put the operation on the queue. */
+ (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
+
+ queue_start();
+
+ return NRF_SUCCESS;
+}
+
+
+static uint8_t const * rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return (uint8_t*)addr;
+}
+
+
+static uint8_t * wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(addr);
+
+ /* Not supported. */
+ return NULL;
+}
+
+
+static bool is_busy(nrf_fstorage_t const * p_fs)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return (m_flags.state != NRF_FSTORAGE_STATE_IDLE);
+}
+
+
+void nrf_fstorage_sys_evt_handler(uint32_t sys_evt, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ if ( (sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS)
+ && (sys_evt != NRF_EVT_FLASH_OPERATION_ERROR))
+ {
+ /* Ignore any non-flash events. */
+ return;
+ }
+
+ switch (m_flags.state)
+ {
+ case NRF_FSTORAGE_STATE_IDLE:
+ /* Ignore flash events if no flash operation was requested. */
+ return;
+
+ case NRF_FSTORAGE_STATE_OP_PENDING:
+ /* The SoftDevice has completed a flash operation that was not requested by fstorage.
+ * It should be possible to request an operation now.
+ * Process the queue at the end of this function. */
+ break;
+
+ case NRF_FSTORAGE_STATE_OP_EXECUTING:
+ {
+ /* Handle the result of a flash operation initiated by this module. */
+ bool operation_finished = false;
+
+ switch (sys_evt)
+ {
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ operation_finished = on_operation_success(m_p_cur_op);
+ break;
+
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ operation_finished = on_operation_failure(m_p_cur_op);
+ break;
+
+ default:
+ break;
+ }
+
+ if (operation_finished)
+ {
+ /* The operation has finished. Change state to NRF_FSTORAGE_STATE_IDLE
+ * so that queue_process() will fetch a new operation from the queue. */
+ m_flags.state = NRF_FSTORAGE_STATE_IDLE;
+
+ event_send(m_p_cur_op, (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) ?
+ NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+
+ /* Free the queue element after sending out the event to prevent API calls made
+ * in the event context to queue elements indefinitely, without this function
+ * ever returning in case the SoftDevice calls are synchronous. */
+ queue_free();
+ }
+ } break;
+ }
+
+ if (!m_flags.paused)
+ {
+ queue_process();
+ }
+ else
+ {
+ /* A flash operation has completed. Let the SoftDevice change state. */
+ (void) nrf_sdh_request_continue();
+ }
+}
+
+
+bool nrf_fstorage_sdh_req_handler(nrf_sdh_req_evt_t req, void * p_context)
+{
+ UNUSED_PARAMETER(req);
+ UNUSED_PARAMETER(p_context);
+
+ m_flags.paused = true;
+
+ /* If there are any operations ongoing, pause the SoftDevice state change. */
+ return (m_flags.state == NRF_FSTORAGE_STATE_IDLE);
+}
+
+
+void nrf_fstorage_sdh_state_handler(nrf_sdh_state_evt_t state, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ if ( (state == NRF_SDH_EVT_STATE_ENABLED)
+ || (state == NRF_SDH_EVT_STATE_DISABLED))
+ {
+ m_flags.paused = false;
+ m_flags.sd_enabled = (state == NRF_SDH_EVT_STATE_ENABLED);
+
+ /* Execute any operations still in the queue. */
+ queue_process();
+ }
+}
+
+
+/* Exported API implementation. */
+nrf_fstorage_api_t nrf_fstorage_sd =
+{
+ .init = init,
+ .uninit = uninit,
+ .read = read,
+ .write = write,
+ .erase = erase,
+ .rmap = rmap,
+ .wmap = wmap,
+ .is_busy = is_busy
+};
+
+
+#endif // NRF_FSTORAGE_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h
new file mode 100644
index 0000000..b35d15f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ *
+ * @defgroup nrf_fstorage_sd SoftDevice implementation
+ * @ingroup nrf_fstorage
+ * @{
+ *
+ * @brief API implementation of fstorage that uses the SoftDevice.
+*/
+
+#ifndef NRF_FSTORAGE_SD_H__
+#define NRF_FSTORAGE_SD_H__
+
+#include "nrf_fstorage.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief API implementation that uses the SoftDevice.
+ *
+ * @details An fstorage instance with this API implementation can be initialized by providing
+ * this structure as a parameter to @ref nrf_fstorage_init.
+ * The structure is defined in @c nrf_fstorage_sd.c.
+ */
+extern nrf_fstorage_api_t nrf_fstorage_sd;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FSTORAGE_SD_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c
new file mode 100644
index 0000000..bd8aedc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c
@@ -0,0 +1,628 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_GFX)
+
+#include "nrf_gfx.h"
+#include <stdlib.h>
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME gfx
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static inline void pixel_draw(nrf_lcd_t const * p_instance,
+ uint16_t x,
+ uint16_t y,
+ uint32_t color)
+{
+ uint16_t lcd_width = nrf_gfx_width_get(p_instance);
+ uint16_t lcd_height = nrf_gfx_height_get(p_instance);
+
+ if ((x >= lcd_width) || (y >= lcd_height))
+ {
+ return;
+ }
+
+ p_instance->lcd_pixel_draw(x, y, color);
+}
+
+static void rect_draw(nrf_lcd_t const * p_instance,
+ uint16_t x,
+ uint16_t y,
+ uint16_t width,
+ uint16_t height,
+ uint32_t color)
+{
+ uint16_t lcd_width = nrf_gfx_width_get(p_instance);
+ uint16_t lcd_height = nrf_gfx_height_get(p_instance);
+
+ if ((x >= lcd_width) || (y >= lcd_height))
+ {
+ return;
+ }
+
+ if (width > (lcd_width - x))
+ {
+ width = lcd_width - x;
+ }
+
+ if (height > (lcd_height - y))
+ {
+ height = lcd_height - y;
+ }
+
+ p_instance->lcd_rect_draw(x, y, width, height, color);
+}
+
+static void line_draw(nrf_lcd_t const * p_instance,
+ uint16_t x_0,
+ uint16_t y_0,
+ uint16_t x_1,
+ int16_t y_1,
+ uint32_t color)
+{
+ uint16_t x = x_0;
+ uint16_t y = y_0;
+ int16_t d;
+ int16_t d_1;
+ int16_t d_2;
+ int16_t ai;
+ int16_t bi;
+ int16_t xi = (x_0 < x_1) ? 1 : (-1);
+ int16_t yi = (y_0 < y_1) ? 1 : (-1);
+ bool swapped = false;
+
+ d_1 = abs(x_1 - x_0);
+ d_2 = abs(y_1 - y_0);
+
+ pixel_draw(p_instance, x, y, color);
+
+ if (d_1 < d_2)
+ {
+ d_1 = d_1 ^ d_2;
+ d_2 = d_1 ^ d_2;
+ d_1 = d_2 ^ d_1;
+ swapped = true;
+ }
+
+ ai = (d_2 - d_1) * 2;
+ bi = d_2 * 2;
+ d = bi - d_1;
+
+ while ((y != y_1) || (x != x_1))
+ {
+ if (d >= 0)
+ {
+ x += xi;
+ y += yi;
+ d += ai;
+ }
+ else
+ {
+ d += bi;
+ if (swapped)
+ {
+ y += yi;
+ }
+ else
+ {
+ x += xi;
+ }
+ }
+ pixel_draw(p_instance, x, y, color);
+ }
+}
+
+static void write_character(nrf_lcd_t const * p_instance,
+ nrf_gfx_font_desc_t const * p_font,
+ uint8_t character,
+ uint16_t * p_x,
+ uint16_t y,
+ uint16_t font_color)
+{
+ uint8_t char_idx = character - p_font->startChar;
+ uint16_t bytes_in_line = CEIL_DIV(p_font->charInfo[char_idx].widthBits, 8);
+
+ if (character == ' ')
+ {
+ *p_x += p_font->height / 2;
+ return;
+ }
+
+ for (uint16_t i = 0; i < p_font->height; i++)
+ {
+ for (uint16_t j = 0; j < bytes_in_line; j++)
+ {
+ for (uint8_t k = 0; k < 8; k++)
+ {
+ if ((1 << (7 - k)) &
+ p_font->data[p_font->charInfo[char_idx].offset + i * bytes_in_line + j])
+ {
+ pixel_draw(p_instance, *p_x + j * 8 + k, y + i, font_color);
+ }
+ }
+ }
+ }
+
+ *p_x += p_font->charInfo[char_idx].widthBits + p_font->spacePixels;
+}
+
+ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_instance->lcd_init != NULL);
+ ASSERT(p_instance->lcd_uninit != NULL);
+ ASSERT(p_instance->lcd_pixel_draw != NULL);
+ ASSERT(p_instance->lcd_rect_draw != NULL);
+ ASSERT(p_instance->lcd_display != NULL);
+ ASSERT(p_instance->lcd_rotation_set != NULL);
+ ASSERT(p_instance->lcd_display_invert != NULL);
+ ASSERT(p_instance->p_lcd_cb != NULL);
+
+ ret_code_t err_code;
+
+ err_code = p_instance->lcd_init();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_instance->p_lcd_cb->state = NRFX_DRV_STATE_INITIALIZED;
+ }
+
+ return err_code;
+}
+
+void nrf_gfx_uninit(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ p_instance->p_lcd_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
+
+ p_instance->lcd_uninit();
+}
+
+void nrf_gfx_point_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_point_t const * p_point,
+ uint32_t color)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_point != NULL);
+
+ pixel_draw(p_instance, p_point->x, p_point->y, color);
+}
+
+ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_line_t const * p_line,
+ uint32_t color)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_line != NULL);
+
+ uint16_t x_thick = 0;
+ uint16_t y_thick = 0;
+
+ if (((p_line->x_start > nrf_gfx_width_get(p_instance)) &&
+ (p_line->x_end > nrf_gfx_height_get(p_instance))) ||
+ ((p_line->y_start > nrf_gfx_width_get(p_instance)) &&
+ (p_line->y_end > nrf_gfx_height_get(p_instance))))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (abs(p_line->x_start - p_line->x_end) > abs(p_line->y_start - p_line->y_end))
+ {
+ y_thick = p_line->thickness;
+ }
+ else
+ {
+ x_thick = p_line->thickness;
+ }
+
+ if ((p_line->x_start == p_line->x_end) || (p_line->y_start == p_line->y_end))
+ {
+ rect_draw(p_instance,
+ p_line->x_start,
+ p_line->y_start,
+ abs(p_line->x_end - p_line->x_start) + x_thick,
+ abs(p_line->y_end - p_line->y_start) + y_thick,
+ color);
+ }
+ else
+ {
+ if (x_thick > 0)
+ {
+ for (uint16_t i = 0; i < p_line->thickness; i++)
+ {
+ line_draw(p_instance,
+ p_line->x_start + i,
+ p_line->y_start,
+ p_line->x_end + i,
+ p_line->y_end,
+ color);
+ }
+ }
+ else if (y_thick > 0)
+ {
+ for (uint16_t i = 0; i < p_line->thickness; i++)
+ {
+ line_draw(p_instance,
+ p_line->x_start,
+ p_line->y_start + i,
+ p_line->x_end,
+ p_line->y_end + i,
+ color);
+ }
+ }
+ else
+ {
+ line_draw(p_instance,
+ p_line->x_start + x_thick,
+ p_line->y_start + y_thick,
+ p_line->x_end + x_thick,
+ p_line->y_end + y_thick,
+ color);
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_circle_t const * p_circle,
+ uint32_t color,
+ bool fill)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_circle != NULL);
+
+ int16_t y = 0;
+ int16_t err = 0;
+ int16_t x = p_circle->r;
+
+ if ((p_circle->x - p_circle->r > nrf_gfx_width_get(p_instance)) ||
+ (p_circle->y - p_circle->r > nrf_gfx_height_get(p_instance)))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ while (x >= y)
+ {
+ if (fill)
+ {
+ if ((-y + p_circle->x < 0) || (-x + p_circle->x < 0))
+ {
+ rect_draw(p_instance, 0, (-x + p_circle->y), (y + p_circle->x + 1), 1, color);
+ rect_draw(p_instance, 0, (-y + p_circle->y), (x + p_circle->x + 1), 1, color);
+ rect_draw(p_instance, 0, (y + p_circle->y), (x + p_circle->x + 1), 1, color);
+ rect_draw(p_instance, 0, (x + p_circle->y), (y + p_circle->x + 1), 1, color);
+ }
+ else
+ {
+ rect_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), (2 * y + 1), 1, color);
+ rect_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), (2 * x + 1), 1, color);
+ rect_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), (2 * x + 1), 1, color);
+ rect_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), (2 * y + 1), 1, color);
+ }
+ }
+ else
+ {
+ pixel_draw(p_instance, (y + p_circle->x), (x + p_circle->y), color);
+ pixel_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), color);
+ pixel_draw(p_instance, (x + p_circle->x), (y + p_circle->y), color);
+ pixel_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), color);
+ pixel_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), color);
+ pixel_draw(p_instance, (y + p_circle->x), (-x + p_circle->y), color);
+ pixel_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), color);
+ pixel_draw(p_instance, (x + p_circle->x), (-y + p_circle->y), color);
+ }
+
+ if (err <= 0)
+ {
+ y += 1;
+ err += 2 * y + 1;
+ }
+ if (err > 0)
+ {
+ x -= 1;
+ err -= 2 * x + 1;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t thickness,
+ uint32_t color,
+ bool fill)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_rect != NULL);
+
+ uint16_t rect_width = p_rect->width - thickness;
+ uint16_t rect_height = p_rect->height - thickness;
+
+ if ((p_rect->width == 1) ||
+ (p_rect->height == 1) ||
+ (thickness * 2 > p_rect->width) ||
+ (thickness * 2 > p_rect->height) ||
+ ((p_rect->x > nrf_gfx_width_get(p_instance)) &&
+ (p_rect->y > nrf_gfx_height_get(p_instance))))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+
+ if (fill)
+ {
+ rect_draw(p_instance,
+ p_rect->x,
+ p_rect->y,
+ p_rect->width,
+ p_rect->height,
+ color);
+ }
+ else
+ {
+ nrf_gfx_line_t line;
+
+ // Top horizontal line.
+ line.x_start = p_rect->x;
+ line.y_start = p_rect->y;
+ line.x_end = p_rect->x + p_rect->width;
+ line.y_end = p_rect->y;
+ line.thickness = thickness;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ // Bottom horizontal line.
+ line.x_start = p_rect->x;
+ line.y_start = p_rect->y + rect_height;
+ line.x_end = p_rect->x + p_rect->width;
+ line.y_end = p_rect->y + rect_height;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ // Left vertical line.
+ line.x_start = p_rect->x;
+ line.y_start = p_rect->y + thickness;
+ line.x_end = p_rect->x;
+ line.y_end = p_rect->y + rect_height;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ // Right vertical line.
+ line.x_start = p_rect->x + rect_width;
+ line.y_start = p_rect->y + thickness;
+ line.x_end = p_rect->x + rect_width;
+ line.y_end = p_rect->y + rect_height;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ }
+
+ return NRF_SUCCESS;
+}
+
+void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color)
+{
+ rect_draw(p_instance, 0, 0, nrf_gfx_width_get(p_instance), nrf_gfx_height_get(p_instance), color);
+}
+
+ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t const * img_buf)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_rect != NULL);
+ ASSERT(img_buf != NULL);
+
+ if ((p_rect->x > nrf_gfx_width_get(p_instance)) || (p_rect->y > nrf_gfx_height_get(p_instance)))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ size_t idx;
+ uint16_t pixel;
+ uint8_t padding = p_rect->width % 2;
+
+ for (int32_t i = 0; i < p_rect->height; i++)
+ {
+ for (uint32_t j = 0; j < p_rect->width; j++)
+ {
+ idx = (uint32_t)((p_rect->height - i - 1) * (p_rect->width + padding) + j);
+
+ pixel = (img_buf[idx] >> 8) | (img_buf[idx] << 8);
+
+ pixel_draw(p_instance, p_rect->x + j, p_rect->y + i, pixel);
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(img_buf != NULL);
+
+ const nrf_gfx_rect_t rectangle =
+ {
+ .x = 0,
+ .y = 0,
+ .width = nrf_gfx_width_get(p_instance),
+ .height = nrf_gfx_height_get(p_instance)
+ };
+
+ (void)nrf_gfx_bmp565_draw(p_instance, &rectangle, img_buf);
+}
+
+void nrf_gfx_display(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ p_instance->lcd_display();
+}
+
+void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ bool rotated = (bool)(p_instance->p_lcd_cb->rotation % 2);
+
+ uint16_t height = !rotated ? nrf_gfx_height_get(p_instance) :
+ nrf_gfx_width_get(p_instance);
+ uint16_t width = !rotated ? nrf_gfx_width_get(p_instance) :
+ nrf_gfx_height_get(p_instance);
+
+ p_instance->p_lcd_cb->rotation = rotation;
+
+ switch (rotation) {
+ case NRF_LCD_ROTATE_0:
+ p_instance->p_lcd_cb->height = height;
+ p_instance->p_lcd_cb->width = width;
+ break;
+ case NRF_LCD_ROTATE_90:
+ p_instance->p_lcd_cb->height = width;
+ p_instance->p_lcd_cb->width = height;
+ break;
+ case NRF_LCD_ROTATE_180:
+ p_instance->p_lcd_cb->height = height;
+ p_instance->p_lcd_cb->width = width;
+ break;
+ case NRF_LCD_ROTATE_270:
+ p_instance->p_lcd_cb->height = width;
+ p_instance->p_lcd_cb->width = height;
+ break;
+ default:
+ break;
+ }
+
+ p_instance->lcd_rotation_set(rotation);
+}
+
+void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert)
+{
+ ASSERT(p_instance != NULL);
+
+ p_instance->lcd_display_invert(invert);
+}
+
+ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance,
+ nrf_gfx_point_t const * p_point,
+ uint16_t font_color,
+ const char * string,
+ const nrf_gfx_font_desc_t * p_font,
+ bool wrap)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_point != NULL);
+ ASSERT(string != NULL);
+ ASSERT(p_font != NULL);
+
+ uint16_t x = p_point->x;
+ uint16_t y = p_point->y;
+
+ if (y > (nrf_gfx_height_get(p_instance) - p_font->height))
+ {
+ // Not enough space to write even single char.
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ for (size_t i = 0; string[i] != '\0' ; i++)
+ {
+ if (string[i] == '\n')
+ {
+ x = p_point->x;
+ y += p_font->height + p_font->height / 10;
+ }
+ else
+ {
+ write_character(p_instance, p_font, (uint8_t)string[i], &x, y, font_color);
+ }
+
+ uint8_t char_idx = string[i] - p_font->startChar;
+ uint16_t char_width = string[i] == ' ' ? (p_font->height / 2) :
+ p_font->charInfo[char_idx].widthBits;
+
+ if (x > (nrf_gfx_width_get(p_instance) - char_width))
+ {
+ if (wrap)
+ {
+ x = p_point->x;
+ y += p_font->height + p_font->height / 10;
+ }
+ else
+ {
+ break;
+ }
+
+ if (y > (nrf_gfx_height_get(p_instance) - p_font->height))
+ {
+ break;
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ return p_instance->p_lcd_cb->height;
+}
+
+uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ return p_instance->p_lcd_cb->width;
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_GFX)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h
new file mode 100644
index 0000000..dcc4e77
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h
@@ -0,0 +1,320 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_GFX_H__
+#define NRF_GFX_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "nrf_lcd.h"
+#include "nrf_font.h"
+
+/** @file
+ *
+ * @addtogroup ili9341_config
+ * @ingroup ext_drivers
+ *
+ * @addtogroup st7735_config
+ * @ingroup ext_drivers
+ *
+ * @defgroup nrf_gfx GFX Library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for drawing graphical objects like lines, circles, and rectangles.
+ Provides support for different fonts.
+ */
+
+/**
+ * @brief GFX point object structure.
+ */
+typedef struct
+{
+ uint16_t x; /**< Horizontal coordinate of the point where to start drawing the object. */
+ uint16_t y; /**< Vertical coordinate of the point where to start drawing the object. */
+}nrf_gfx_point_t;
+
+/**
+ * @brief GFX line object structure.
+ */
+typedef struct
+{
+ uint16_t x_start; /**< Horizontal coordinate of the point where to start drawing the object. */
+ uint16_t y_start; /**< Vertical coordinate of the point where to start drawing the object. */
+ uint16_t x_end; /**< Horizontal coordinate of the point where to end drawing the object. */
+ uint16_t y_end; /**< Vertical coordinate of the point where to end drawing the object. */
+ uint16_t thickness; /**< Thickness of the border of the object. */
+}nrf_gfx_line_t;
+
+/**
+ * @brief GFX circle object structure.
+ */
+typedef struct
+{
+ uint16_t x; /**< Horizontal coordinate of the centre of the object. */
+ uint16_t y; /**< Vertical coordinate of the centre of the object. */
+ uint16_t r; /**< Radius of the object. */
+}nrf_gfx_circle_t;
+
+/**
+ * @brief GFX rectangle object structure.
+ */
+typedef struct
+{
+ uint16_t x; /**< Horizontal coordinate of the point where to start drawing the object. */
+ uint16_t y; /**< Vertical coordinate of the point where to start drawing the object. */
+ uint16_t width; /**< Width of the object. */
+ uint16_t height; /**< Height of the object. */
+}nrf_gfx_rect_t;
+
+/**
+ * @defgroup nrf_gfx_macros Macros for defining new graphic objects
+ * @{
+ */
+#define NRF_GFX_POINT(_x, _y) \
+ { \
+ .x = (_x), \
+ .y = (_y) \
+ }
+
+#define NRF_GFX_LINE(_x_0, _y_0, _x_1, _y_1, _thickness) \
+ { \
+ .x_start = (_x_0), \
+ .y_start = (_y_0), \
+ .x_end = (_x_1), \
+ .y_end = (_y_1), \
+ .thickness = (_thickness) \
+ }
+
+#define NRF_GFX_CIRCLE(_x, _y, _radius) \
+ { \
+ .x = (_x), \
+ .y = (_y), \
+ .r = (_radius) \
+ }
+
+#define NRF_GFX_RECT(_x, _y, _width, _height) \
+ { \
+ .x = (_x), \
+ .y = (_y), \
+ .width = (_width), \
+ .height = (_height) \
+ }
+/* @} */
+
+/**
+ * @brief Font descriptor type.
+ */
+typedef FONT_INFO nrf_gfx_font_desc_t;
+
+/**
+ * @brief Function for initializing the GFX library.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ * @return Values returned by @ref nrf_lcd_t::lcd_init.
+ */
+ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for uninitializing the GFX library.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ * @return Values returned by @ref nrf_lcd_t::lcd_uninit.
+ */
+void nrf_gfx_uninit(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for drawing a point.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_point Pointer to the point object.
+ * @param[in] color Color of the object in the display accepted format.
+ */
+void nrf_gfx_point_draw(nrf_lcd_t const * p_instance, nrf_gfx_point_t const * p_point, uint32_t color);
+
+/**
+ * @brief Function for drawing a line.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_line Pointer to the line object.
+ * @param[in] color Color of the object in the display accepted format.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen.
+ * @retval NRF_SUCCESS If object was successfully drawn.
+ */
+ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance, nrf_gfx_line_t const * p_line, uint32_t color);
+
+/**
+ * @brief Function for drawing a circle.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_circle Pointer to the circle object.
+ * @param[in] color Color of the object in the display accepted format.
+ * @param[in] fill If true, the circle will be filled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen.
+ * @retval NRF_SUCCESS If object was successfully drawn.
+ *
+ * @note The height and width of the drawn circle are determined by: radius * 2 + 1.
+ *
+ */
+ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_circle_t const * p_circle,
+ uint32_t color,
+ bool fill);
+
+/**
+ * @brief Function for drawing a rectangle.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_rect Pointer to the rectangle object.
+ * @param[in] thickness Thickness of the rectangle border.
+ * @param[in] color Color of the object in the display accepted format.
+ * @param[in] fill If true, the rectangle will be filled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen.
+ * @retval NRF_SUCCESS If object was successfully drawn.
+ */
+ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t thickness,
+ uint32_t color,
+ bool fill);
+
+/**
+ * @brief Function for filling the screen with selected color.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] color Color of the screen in the display accepted format.
+ */
+void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color);
+
+/**
+ * @brief Function for drawing an image from a .bmp file.
+ *
+ * Data in img_buf is expected to be stored in 2-byte samples, little endianness, RGB565 format.
+ * Pointer should skip the header and point to the first byte of data.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_rect Pointer to the rectangle object.
+ * @param[in] img_buf Pointer to data from the .bmp file.
+ *
+ * @note Only compatible with displays that accept pixels in RGB565 format.
+ */
+ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t const * img_buf);
+
+/**
+ * @brief Function for drawing an image from a .bmp file.
+ *
+ * Data in img_buf is expected to be stored in 2-byte samples, little endianness, RGB565 format.
+ * Pointer should skip the header and point to the first byte of data.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] img_buf Pointer to data from the .bmp file.
+ *
+ * @note Only compatible with displays that accept pixels in RGB565 format.
+ */
+void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf);
+
+/**
+ * @brief Function for displaying data from an internal frame buffer.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ */
+void nrf_gfx_display(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for setting screen rotation.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] rotation Rotation to be made.
+ */
+void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation);
+
+/**
+ * @brief Function for setting inversion of colors.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] invert If true, inversion will be set.
+ */
+void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert);
+
+/**
+ * @brief Function for printing a string to the screen.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_point Pointer to the point where to start drawing the object.
+ * @param[in] font_color Color of the font in the display accepted format.
+ * @param[in] p_string Pointer to the string.
+ * @param[in] p_font Pointer to the font descriptor.
+ * @param[in] wrap If true, the string will be wrapped to the new line.
+ */
+ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance,
+ nrf_gfx_point_t const * p_point,
+ uint16_t font_color,
+ const char * p_string,
+ const nrf_gfx_font_desc_t * p_font,
+ bool wrap);
+
+/**
+ * @brief Function for getting the height of the screen.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ */
+uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for getting the width of the screen.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ */
+uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance);
+
+/* @} */
+
+#endif //NRF_GFX_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h
new file mode 100644
index 0000000..04202c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h
@@ -0,0 +1,144 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_LCD_H__
+#define NRF_LCD_H__
+
+#include <nrfx.h>
+
+/** @file
+ *
+ * @defgroup nrf_lcd LCD Library
+ * @{
+ * @ingroup nrf_gfx
+ *
+ * @brief This module defines generic API for LCDs.
+ */
+
+/**
+ * @brief Enumerator with available rotations.
+ */
+typedef enum{
+ NRF_LCD_ROTATE_0 = 0, /**< Rotate 0 degrees, clockwise. */
+ NRF_LCD_ROTATE_90, /**< Rotate 90 degrees, clockwise. */
+ NRF_LCD_ROTATE_180, /**< Rotate 180 degrees, clockwise. */
+ NRF_LCD_ROTATE_270 /**< Rotate 270 degrees, clockwise. */
+}nrf_lcd_rotation_t;
+
+/**
+ * @brief LCD instance control block.
+ */
+typedef struct
+{
+ nrfx_drv_state_t state; /**< State of LCD instance. */
+ uint16_t height; /**< LCD height. */
+ uint16_t width; /**< LCD width. */
+ nrf_lcd_rotation_t rotation; /**< LCD rotation. */
+}lcd_cb_t;
+
+/**
+ * @brief LCD instance type.
+ *
+ * This structure provides generic API for LCDs.
+ */
+typedef struct
+{
+ /**
+ * @brief Function for initializing the LCD controller.
+ */
+ ret_code_t (* lcd_init)(void);
+
+ /**
+ * @brief Function for uninitializing the LCD controller.
+ */
+ void (* lcd_uninit)(void);
+
+ /**
+ * @brief Function for drawing a single pixel.
+ *
+ * @param[in] x Horizontal coordinate of the pixel.
+ * @param[in] y Vertical coordinate of the pixel.
+ * @param[in] color Color of the pixel in LCD accepted format.
+ */
+ void (* lcd_pixel_draw)(uint16_t x, uint16_t y, uint32_t color);
+
+ /**
+ * @brief Function for drawing a filled rectangle.
+ *
+ * @param[in] x Horizontal coordinate of the point where to start drawing the rectangle.
+ * @param[in] y Vertical coordinate of the point where to start drawing the rectangle.
+ * @param[in] width Width of the image.
+ * @param[in] height Height of the image.
+ * @param[in] color Color with which to fill the rectangle in LCD accepted format.
+ */
+ void (* lcd_rect_draw)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color);
+
+ /**
+ * @brief Function for displaying data from an internal frame buffer.
+ *
+ * This function may be used when functions for drawing do not write directly to
+ * LCD but to an internal frame buffer. It could be implemented to write data from this
+ * buffer to LCD.
+ */
+ void (* lcd_display)(void);
+
+ /**
+ * @brief Function for rotating the screen.
+ *
+ * @param[in] rotation Rotation as enumerated value.
+ */
+ void (* lcd_rotation_set)(nrf_lcd_rotation_t rotation);
+
+ /**
+ * @brief Function for setting inversion of colors on the screen.
+ *
+ * @param[in] invert If true, inversion will be set.
+ */
+ void (* lcd_display_invert)(bool invert);
+
+ /**
+ * @brief Pointer to the LCD instance control block.
+ */
+ lcd_cb_t * p_lcd_cb;
+}nrf_lcd_t;
+
+/* @} */
+
+#endif // NRF_LCD_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c
new file mode 100644
index 0000000..4457ca6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_GPIOTE)
+#include "app_gpiote.h"
+#include "nrf_bitmask.h"
+#define MODULE_INITIALIZED (mp_users != NULL) /**< Macro designating whether the module has been initialized properly. */
+
+/**@brief GPIOTE user type. */
+typedef struct
+{
+ uint32_t pins_mask[GPIO_COUNT]; /**< Mask defining which pins user wants to monitor. */
+ uint32_t pins_low_to_high_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling low->high. */
+ uint32_t pins_high_to_low_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling high->low. */
+ uint32_t sense_high_pins[GPIO_COUNT]; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */
+ app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */
+ bool enabled; /**< Flag indicating whether user is enabled. */
+} gpiote_user_t;
+
+STATIC_ASSERT(sizeof(gpiote_user_t) <= GPIOTE_USER_NODE_SIZE);
+STATIC_ASSERT(sizeof(gpiote_user_t) % 4 == 0);
+
+static uint8_t m_user_array_size; /**< Size of user array. */
+static uint8_t m_user_count; /**< Number of registered users. */
+static gpiote_user_t * mp_users = NULL; /**< Array of GPIOTE users. */
+static uint32_t m_pins[GPIO_COUNT]; /**< Mask of initialized pins. */
+static uint32_t m_last_pins_state[GPIO_COUNT]; /**< Most recent state of pins. */
+
+void gpiote_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
+{
+ int i;
+ uint32_t pin_mask[GPIO_COUNT] = {0};
+ uint32_t empty_pin_mask[GPIO_COUNT] = {0};
+ nrf_bitmask_bit_set(pin, pin_mask);
+ bool hitolo = nrf_bitmask_bit_is_set(pin, m_last_pins_state);
+ nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state);
+
+ for (i = 0; i < m_user_count; i++)
+ {
+ if (mp_users[i].enabled && nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask))
+ {
+ if (
+ nrf_bitmask_bit_is_set(pin, mp_users[i].pins_high_to_low_mask)
+ && hitolo)
+ {
+ mp_users[i].event_handler(empty_pin_mask,pin_mask);
+ }
+ else if (
+ nrf_bitmask_bit_is_set(pin, mp_users[i].pins_low_to_high_mask)
+ && !hitolo)
+ {
+ mp_users[i].event_handler(pin_mask,empty_pin_mask);
+ }
+ }
+ }
+}
+
+uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer)
+{
+ uint32_t ret_code = NRF_SUCCESS;
+
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Check that buffer is correctly aligned.
+ if (!is_word_aligned(p_buffer))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Initialize file globals.
+ mp_users = (gpiote_user_t *)p_buffer;
+ m_user_array_size = max_users;
+ m_user_count = 0;
+ memset(m_pins,0, sizeof(m_pins));
+
+ memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t));
+
+ if (nrf_drv_gpiote_is_init()==false)
+ {
+ ret_code = nrf_drv_gpiote_init();
+ }
+
+ return ret_code;
+}
+
+uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id,
+ uint32_t const * p_pins_low_to_high_mask,
+ uint32_t const * p_pins_high_to_low_mask,
+ app_gpiote_event_handler_t event_handler)
+{
+ uint32_t user_pin_mask[GPIO_COUNT];
+ ASSERT(event_handler != NULL);
+
+ // Check state and parameters.
+ VERIFY_MODULE_INITIALIZED();
+
+ if (m_user_count >= m_user_array_size)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ nrf_bitmask_masks_or(p_pins_low_to_high_mask, p_pins_high_to_low_mask,
+ user_pin_mask, sizeof(user_pin_mask));
+ // Allocate new user.
+ mp_users[m_user_count].enabled = false;
+ mp_users[m_user_count].event_handler = event_handler;
+
+ memcpy(mp_users[m_user_count].pins_mask,
+ user_pin_mask,
+ sizeof(mp_users[m_user_count].pins_mask));
+ memcpy(mp_users[m_user_count].pins_low_to_high_mask,
+ p_pins_low_to_high_mask,
+ sizeof(mp_users[m_user_count].pins_low_to_high_mask));
+ memcpy(mp_users[m_user_count].pins_high_to_low_mask,
+ p_pins_high_to_low_mask,
+ sizeof(mp_users[m_user_count].pins_high_to_low_mask));
+
+ uint32_t i;
+ const nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
+
+ uint32_t num_of_pins = NUMBER_OF_PINS ;
+ for (i = 0; i < num_of_pins; i++)
+ {
+ if (nrf_bitmask_bit_is_set(i, user_pin_mask) &&
+ !nrf_bitmask_bit_is_set(i, m_pins))
+ {
+ uint32_t ret_val = nrf_drv_gpiote_in_init(i, &config, gpiote_handler);
+ VERIFY_SUCCESS(ret_val);
+ nrf_bitmask_bit_set(i, m_pins);
+ }
+ }
+
+ /* Success - return user id and increment counter */
+ *p_user_id = m_user_count++;
+ return NRF_SUCCESS;
+}
+
+uint32_t app_gpiote_user_register_ex(app_gpiote_user_id_t * p_user_id,
+ app_gpiote_user_pin_config_t const * p_pins_config,
+ size_t pin_count,
+ app_gpiote_event_handler_t event_handler)
+{
+ ASSERT(event_handler != NULL);
+
+ // Check state and parameters.
+ VERIFY_MODULE_INITIALIZED();
+ if (m_user_count >= m_user_array_size)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ /* Prepare user structure */
+ gpiote_user_t * p_user = &mp_users[m_user_count];
+
+ p_user->enabled = false;
+ memset(p_user, 0, sizeof(gpiote_user_t));
+ mp_users[m_user_count].event_handler = event_handler;
+
+ for (; pin_count != 0; --pin_count, ++p_pins_config)
+ {
+ nrfx_gpiote_pin_t pin = (nrfx_gpiote_pin_t)p_pins_config->pin_number;
+ const nrf_drv_gpiote_in_config_t config = GPIOTE_RAW_CONFIG_IN_SENSE_TOGGLE(false);
+ if (!nrf_bitmask_bit_is_set(pin, m_pins))
+ {
+ uint32_t ret_val = nrf_drv_gpiote_in_init(pin, &config, gpiote_handler);
+ VERIFY_SUCCESS(ret_val);
+ nrf_bitmask_bit_set(pin, m_pins);
+ }
+
+ //lint -save -e650 Lint seems not properly support bitfields that uses enum as a base type
+ if ((p_pins_config->sense == NRF_GPIOTE_POLARITY_LOTOHI) ||
+ (p_pins_config->sense == NRF_GPIOTE_POLARITY_TOGGLE))
+ {
+ nrf_bitmask_bit_set(pin, p_user->pins_low_to_high_mask);
+ }
+ if ((p_pins_config->sense == NRF_GPIOTE_POLARITY_HITOLO) ||
+ (p_pins_config->sense == NRF_GPIOTE_POLARITY_TOGGLE))
+ {
+ nrf_bitmask_bit_set(pin, p_user->pins_high_to_low_mask);
+ }
+ //lint -restore
+ }
+ /* Mark all pins used by the selected user */
+ nrf_bitmask_masks_or(
+ p_user->pins_low_to_high_mask,
+ p_user->pins_high_to_low_mask,
+ p_user->pins_mask,
+ sizeof(p_user->pins_mask));
+ /* Success - return user id and increment counter */
+ *p_user_id = m_user_count++;
+
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t error_check(app_gpiote_user_id_t user_id)
+{
+ // Check state and parameters.
+ VERIFY_MODULE_INITIALIZED();
+
+ if (user_id >= m_user_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return NRF_SUCCESS;
+}
+/**
+ * @brief Function for enabling event on pin (if not yet enabled) or disabling the event if no other
+ * user requires it.
+ *
+ * @param pin Pin to enable
+ * @param enable If true function will attempt to enable the pin else it will attempt to disable it.
+ */
+static void pin_event_enable(uint32_t pin, bool enable)
+{
+ uint32_t i;
+ bool enabled = false;
+ //search if any user already enabled given pin
+ for (i = 0; i < m_user_count; i++)
+ {
+ if (mp_users[i].enabled &&
+ nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask))
+ {
+ enabled = true;
+ break;
+ }
+ }
+ if (!enabled)
+ {
+ if (enable)
+ {
+ nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state);
+ nrf_drv_gpiote_in_event_enable(pin, true);
+ }
+ else
+ {
+ nrf_drv_gpiote_in_event_disable(pin);
+ }
+ }
+}
+
+/**
+ * @brief Function for enabling or disabling events for pins used by the user.
+ *
+ * Function will enable pin events only if they are not yet enabled. Function will disable pin
+ * events only if there is no other enabled user that is using them.
+ *
+ * @param user_id User id.
+ * @param enable If true function will attempt to enable the pin else it will attempt to disable it.
+ */
+static uint32_t user_enable(app_gpiote_user_id_t user_id, bool enable)
+{
+ uint32_t ret_code = error_check(user_id);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ uint32_t i;
+ for (i = 0; i < NUMBER_OF_PINS; i++)
+ {
+ if (nrf_bitmask_bit_is_set(i, mp_users[user_id].pins_mask))
+ {
+ pin_event_enable(i, enable);
+ }
+ }
+ }
+ return ret_code;
+}
+
+uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id)
+{
+ uint32_t ret_code = NRF_SUCCESS;
+
+ if (mp_users[user_id].enabled == false)
+ {
+ ret_code = user_enable(user_id, true);
+ VERIFY_SUCCESS(ret_code);
+
+ mp_users[user_id].enabled = true;
+ return ret_code;
+ }
+ else
+ {
+ return ret_code;
+ }
+}
+
+uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id)
+{
+ uint32_t ret_code = NRF_SUCCESS;
+
+ if (mp_users[user_id].enabled)
+ {
+ mp_users[user_id].enabled = false;
+ ret_code = user_enable(user_id, false);
+ }
+
+ return ret_code;
+}
+
+uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins)
+{
+ gpiote_user_t * p_user;
+ uint32_t ret_code = error_check(user_id);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ p_user = &mp_users[user_id];
+
+ nrf_gpio_ports_read(0, GPIO_COUNT, p_pins);
+ nrf_bitmask_masks_and(p_pins, p_user->pins_mask, p_pins, sizeof(p_user->pins_mask));
+ }
+ return ret_code;
+}
+#endif //NRF_MODULE_ENABLED(APP_GPIOTE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h
new file mode 100644
index 0000000..2cac21e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h
@@ -0,0 +1,266 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup app_gpiote GPIOTE Handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief GPIOTE handler module.
+ *
+ * @details The GPIOTE handler allows several modules ("users") to share the GPIOTE interrupt,
+ * each user defining a set of pins able to generate events to the user.
+ * When a GPIOTE interrupt occurs, the GPIOTE interrupt handler will call the event handler
+ * of each user for which at least one of the pins generated an event.
+ *
+ * The GPIOTE users are responsible for configuring all their corresponding pins, except
+ * the SENSE field, which should be initialized to GPIO_PIN_CNF_SENSE_Disabled.
+ * The SENSE field will be updated by the GPIOTE module when it is enabled or disabled,
+ * and also while it is enabled.
+ *
+ * The module specifies on which pins events should be generated if the pin(s) goes
+ * from low->high or high->low or both directions.
+ *
+ * @note Even if the application is using the @ref app_scheduler, the GPIOTE event handlers will
+ * be called directly from the GPIOTE interrupt handler.
+ *
+ * @warning If multiple users registers for the same pins the behavior for those pins are undefined.
+ */
+
+#ifndef APP_GPIOTE_H__
+#define APP_GPIOTE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_drv_gpiote.h"
+#include "app_error.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GPIOTE_USER_NODE_SIZE ((4*sizeof(uint32_t)*GPIO_COUNT)+8) /**< Size of app_gpiote.gpiote_user_t (only for use inside APP_GPIOTE_BUF_SIZE()). */
+
+/**@brief Compute number of bytes required to hold the GPIOTE data structures.
+ *
+ * @param[in] MAX_USERS Maximum number of GPIOTE users.
+ *
+ * @retval Required buffer size (in bytes).
+ */
+#define APP_GPIOTE_BUF_SIZE(MAX_USERS) ((MAX_USERS) * GPIOTE_USER_NODE_SIZE)
+
+typedef uint8_t app_gpiote_user_id_t;
+
+/**@brief GPIOTE event handler type. */
+typedef void (*app_gpiote_event_handler_t)(uint32_t const * p_event_pins_low_to_high,
+ uint32_t const * p_event_pins_high_to_low);
+
+/**@brief GPIOTE input event handler type. */
+typedef void (*app_gpiote_input_event_handler_t)(void);
+
+
+/* Make the pin config descriptor packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Single pin configuration
+ *
+ * Structure used to describe single pin configuration
+ * when registering user.
+ * @sa app_gpiote_user_register_ex
+ */
+typedef struct
+{
+ /** Pin number to observe */
+ uint32_t pin_number : VBITS(NRF_GPIO_PIN_MAP(GPIO_COUNT - 1, 31));
+ /** Transition to observe */
+ nrf_gpiote_polarity_t sense : 2;
+} app_gpiote_user_pin_config_t;
+
+// Check if we can fitt all the nrf_gpiote_polarity_t values into 2 bits field
+STATIC_ASSERT(NRF_GPIOTE_POLARITY_LOTOHI <= 3);
+STATIC_ASSERT(NRF_GPIOTE_POLARITY_HITOLO <= 3);
+STATIC_ASSERT(NRF_GPIOTE_POLARITY_TOGGLE <= 3);
+
+#pragma pack(pop)
+
+/**@brief Macro for initializing the GPIOTE module.
+ *
+ * @details It will handle dimensioning and allocation of the memory buffer required by the module,
+ * making sure that the buffer is correctly aligned.
+ *
+ * @param[in] MAX_USERS Maximum number of GPIOTE users.
+ *
+ * @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).
+ */
+/*lint -emacro(506, APP_GPIOTE_INIT) */ /* Suppress "Constant value Boolean */
+#define APP_GPIOTE_INIT(MAX_USERS) \
+ do \
+ { \
+ static uint32_t app_gpiote_buf[CEIL_DIV(APP_GPIOTE_BUF_SIZE(MAX_USERS), sizeof(uint32_t))];\
+ uint32_t ERR_CODE = app_gpiote_init((MAX_USERS), app_gpiote_buf); \
+ APP_ERROR_CHECK(ERR_CODE); \
+ } while (0)
+
+/**@brief Function for initializing the GPIOTE module.
+ *
+ * @note Normally initialization should be done using the APP_GPIOTE_INIT() macro, as that will
+ * allocate the buffer needed by the GPIOTE module (including aligning the buffer correctly).
+ *
+ * @param[in] max_users Maximum number of GPIOTE users.
+ * @param[in] p_buffer Pointer to memory buffer for internal use in the app_gpiote
+ * module. The size of the buffer can be computed using the
+ * APP_GPIOTE_BUF_SIZE() macro. The buffer must be aligned to
+ * a 4 byte boundary.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte
+ * boundary).
+ */
+uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer);
+
+/**@brief Function for registering a GPIOTE user.
+ *
+ * @param[out] p_user_id Id for the new GPIOTE user.
+ * @param[in] p_pins_low_to_high_mask Pointer to word array with mask defining which pins
+ * will generate events to this user when state is changed
+ * from low->high. Size of array depends on number of ports
+ * in the device.
+ * @param[in] p_pins_high_to_low_mask Pointer to word array with mask defining which pins
+ * will generate events to this user when state is changed
+ * from high->low. Size of array depends on number of ports
+ * in the device.
+ * @param[in] event_handler Pointer to function to be executed when an event occurs.
+ * Cannot be NULL.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ * @retval NRF_ERROR_NO_MEM Returned if the application tries to register more users
+ * than defined when the GPIOTE module was initialized in
+ * @ref app_gpiote_init.
+ *
+ * @note The function can also return error codes from internally
+ * called @ref nrf_drv_gpiote_in_init
+ *
+ * @sa app_gpiote_user_register_ex
+ */
+uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id,
+ uint32_t const * p_pins_low_to_high_mask,
+ uint32_t const * p_pins_high_to_low_mask,
+ app_gpiote_event_handler_t event_handler);
+
+/**@brief Function for registering GPIOTE user using pins configuration list.
+ *
+ * Function for registering GPIOTE user that uses array of pins configuration.
+ * This function do not change pins configuration.
+ * Pins must be configured before calling this function.
+ *
+ * @param[out] p_user_id Id for the new GPIOTE user.
+ * @param[in] p_pins_config Pointer to the array of pins configuration for the user.
+ * @param[in] pin_count Number of pins to configure for the user.
+ * @param[in] event_handler Pointer to function to be executed when an event occurs.
+ * Cannot be NULL.
+ *
+ * @retval NRF_SUCCESS Successful user registration.
+ * @retval NRF_ERROR_INVALID_STATE If @ref app_gpiote_init has not been called before calling
+ * this function.
+ * @retval NRF_ERROR_NO_MEM Returned if the application tries to register more users
+ * than defined when the GPIOTE module was initialized in
+ * @ref app_gpiote_init.
+ *
+ * @note The function can also return error codes from internally
+ * called @ref nrf_drv_gpiote_in_init
+ *
+ * @sa app_gpiote_user_register
+ */
+uint32_t app_gpiote_user_register_ex(app_gpiote_user_id_t * p_user_id,
+ app_gpiote_user_pin_config_t const * p_pins_config,
+ size_t pin_count,
+ app_gpiote_event_handler_t event_handler);
+
+/**@brief Function for informing the GPIOTE module that the specified user wants to use the GPIOTE module.
+ *
+ * @param[in] user_id Id of user to enable.
+ *
+ * @retval NRF_SUCCESS On success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ */
+uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id);
+
+/**@brief Function for informing the GPIOTE module that the specified user is done using the GPIOTE module.
+ *
+ * @param[in] user_id Id of user to enable.
+ *
+ * @retval NRF_SUCCESS On success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ */
+uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id);
+
+/**@brief Function for getting the state of the pins which are registered for the specified user.
+ *
+ * @param[in] user_id Id of user to check.
+ * @param[out] p_pins Pointer to array of words with bit mask corresponding to the pins
+ * configured to generate events to the specified user. All bits
+ * corresponding to pins in the state 'high' will have value '1',
+ * all others will have value '0'. Size of array depends on number
+ * of ports in the device.
+ *
+ * @retval NRF_SUCCESS On success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ */
+uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_GPIOTE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h
new file mode 100644
index 0000000..2333623
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef HARDFAULT_H__
+#define HARDFAULT_H__
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @defgroup hardfault_default HardFault exception
+ * @{
+ * @brief Default HardFault exception implementation.
+ * @ingroup app_common
+ */
+
+/**
+ * @brief Contents of the stack.
+ *
+ * This structure is used to re-create the stack layout after a HardFault exception was raised.
+ */
+typedef struct HardFault_stack
+{
+ uint32_t r0; ///< R0 register.
+ uint32_t r1; ///< R1 register.
+ uint32_t r2; ///< R2 register.
+ uint32_t r3; ///< R3 register.
+ uint32_t r12; ///< R12 register.
+ uint32_t lr; ///< Link register.
+ uint32_t pc; ///< Program counter.
+ uint32_t psr; ///< Program status register.
+} HardFault_stack_t;
+
+/**
+ * @brief Function for processing HardFault exceptions.
+ *
+ * An application that needs to process HardFault exceptions should provide an implementation of this function.
+ * It will be called from the HardFault handler.
+ * If no implementation is provided, the library uses a default one, which just restarts the MCU.
+ *
+ * @note If the DEBUG_NRF macro is defined, the software breakpoint is set just before the call
+ * to this function.
+ *
+ * @param p_stack Pointer to the stack bottom.
+ * This pointer might be NULL if the HardFault was called when the main stack was
+ * the active stack and a stack overrun is detected.
+ * In such a situation, the stack pointer is reinitialized to the default position,
+ * and the stack content is lost.
+ */
+void HardFault_process(HardFault_stack_t * p_stack);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HARDFAULT_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h
new file mode 100644
index 0000000..37e3183
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef HARDFAULT_GENHF_H__
+#define HARDFAULT_GENHF_H__
+
+#include "compiler_abstraction.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @defgroup hardfault_genhf Generating HardFaults for testing
+ * @{
+ * @brief Macros and functions used to generate a HardFault in a selected place.
+ * @ingroup hardfault_default
+ *
+ * This functionality is meant to be used while testing the @ref hardfault_default library functionality.
+ */
+
+/**
+ * @brief Function for generating an invalid function pointer HardFault.
+ *
+ * Function tries to jump into illegal address.
+ */
+static inline void hardfault_genhf_invalid_fp(void);
+
+/**
+ * @brief Function for generating an undefined instruction HardFault.
+ *
+ * This function places the value in the code area that is not the legal instruction.
+ */
+static inline void hardfault_genhf_undefined_instr(void);
+
+/**
+ * @brief Function for generating an unaligned LDM access HardFault.
+ *
+ * This function generates fault exception loading values from an unaligned address.
+ */
+static inline void hardfault_genhf_ldm_align(void);
+
+#if defined( __CC_ARM )
+
+static inline __ASM void hardfault_genhf_invalid_fp(void)
+{
+ MOVS r0, #0
+ BLX r0
+}
+
+static inline __ASM void hardfault_genhf_undefined_instr(void)
+{
+ DCI 0xf123
+ DCI 0x4567
+}
+
+static inline __ASM void hardfault_genhf_ldm_align(void)
+{
+ MOVS r0, #1
+ LDM r0!, {r1-r2}
+}
+
+#elif defined( __ICCARM__ )
+
+#pragma inline=forced
+static inline void hardfault_genhf_invalid_fp(void)
+{
+ __ASM volatile(
+ " movs r0, #0 \n"
+ " blx r0 \n"
+ );
+}
+
+#pragma inline=forced
+static inline void hardfault_genhf_undefined_instr(void)
+{
+ __ASM volatile(
+ "DATA \n"
+ " DC16 0xf123 \n"
+ " DC16 0x4567 \n"
+ );
+}
+
+#pragma inline=forced
+static inline void hardfault_genhf_ldm_align(void)
+{
+ __ASM volatile(
+ " movs r0, #1 \n"
+ " ldm r0!, {r1-r2} \n"
+ );
+}
+
+#elif defined( __GNUC__ )
+
+static inline void hardfault_genhf_invalid_fp(void)
+{
+ __ASM volatile(
+ " .syntax unified \n"
+ " movs r0, #0 \n"
+ " blx r0 \n"
+ );
+}
+
+static inline void hardfault_genhf_undefined_instr(void)
+{
+ __ASM volatile(
+ " .hword 0xf123 \n"
+ " .hword 0x4567 \n"
+ );
+}
+
+static inline void hardfault_genhf_ldm_align(void)
+{
+ __ASM volatile(
+ " .syntax unified \n"
+ " movs r0, #1 \n"
+ " ldm r0!, {r1-r2} \n"
+ );
+}
+
+#else
+#error "Unsupported compiler"
+#endif
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HARDFAULT_GENHF_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c
new file mode 100644
index 0000000..02f3ed7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include "hardfault.h"
+#include "nrf.h"
+#include "compiler_abstraction.h"
+#include "app_util_platform.h"
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_soc.h"
+#endif
+#define NRF_LOG_MODULE_NAME hardfault
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if defined(DEBUG_NRF)
+/**
+ * @brief Pointer to the last received stack pointer.
+ *
+ * This pointer is set in the debug version of the HardFault handler.
+ * It helps to debug HardFault reasons.
+ */
+volatile HardFault_stack_t * HardFault_p_stack;
+#endif
+
+/*lint -save -e14 */
+__WEAK void HardFault_process(HardFault_stack_t * p_stack)
+{
+ // Restart the system by default
+ NVIC_SystemReset();
+}
+/*lint -restore */
+
+void HardFault_c_handler(uint32_t * p_stack_address)
+{
+ NRF_LOG_FINAL_FLUSH();
+
+#if (__CORTEX_M == 0x04)
+
+#ifndef CFSR_MMARVALID
+ #define CFSR_MMARVALID (1 << (0 + 7))
+#endif
+
+#ifndef CFSR_BFARVALID
+ #define CFSR_BFARVALID (1 << (8 + 7))
+#endif
+
+ #if defined(DEBUG)
+
+ HardFault_stack_t * p_stack = (HardFault_stack_t *)p_stack_address;
+ static const char *cfsr_msgs[] = {
+ [0] = "The processor has attempted to execute an undefined instruction",
+ [1] = "The processor attempted a load or store at a location that does not permit the operation",
+ [2] = NULL,
+ [3] = "Unstack for an exception return has caused one or more access violations",
+ [4] = "Stacking for an exception entry has caused one or more access violations",
+ [5] = "A MemManage fault occurred during floating-point lazy state preservation",
+ [6] = NULL,
+ [7] = NULL,
+ [8] = "Instruction bus error",
+ [9] = "Data bus error (PC value stacked for the exception return points to the instruction that caused the fault)",
+ [10] = "Data bus error (return address in the stack frame is not related to the instruction that caused the error)",
+ [11] = "Unstack for an exception return has caused one or more BusFaults",
+ [12] = "Stacking for an exception entry has caused one or more BusFaults",
+ [13] = "A bus fault occurred during floating-point lazy state preservation",
+ [14] = NULL,
+ [15] = NULL,
+ [16] = "The processor has attempted to execute an undefined instruction",
+ [17] = "The processor has attempted to execute an instruction that makes illegal use of the EPSR",
+ [18] = "The processor has attempted an illegal load of EXC_RETURN to the PC, as a result of an invalid context, or an invalid EXC_RETURN value",
+ [19] = "The processor has attempted to access a coprocessor",
+ [20] = NULL,
+ [21] = NULL,
+ [22] = NULL,
+ [23] = NULL,
+ [24] = "The processor has made an unaligned memory access",
+ [25] = "The processor has executed an SDIV or UDIV instruction with a divisor of 0",
+ };
+
+ uint32_t cfsr = SCB->CFSR;
+
+ // Print information about error.
+ NRF_LOG_ERROR("HARD FAULT at 0x%08X", p_stack->pc);
+ NRF_LOG_ERROR(" R0: 0x%08X R1: 0x%08X R2: 0x%08X R3: 0x%08X",
+ p_stack->r0, p_stack->r1, p_stack->r2, p_stack->r3);
+ NRF_LOG_ERROR(" R12: 0x%08X LR: 0x%08X PSR: 0x%08X",
+ p_stack->r12, p_stack->lr, p_stack->psr);
+
+ if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk)
+ {
+ NRF_LOG_ERROR("Cause: BusFault on a vector table read during exception processing.");
+ }
+
+ for (uint32_t i = 0; i < sizeof(cfsr_msgs) / sizeof(cfsr_msgs[0]); i++)
+ {
+ if (((cfsr & (1 << i)) != 0) && (cfsr_msgs[i] != NULL))
+ {
+ NRF_LOG_ERROR("Cause: %s.", (uint32_t)cfsr_msgs[i]);
+ }
+ }
+
+ if (cfsr & CFSR_MMARVALID)
+ {
+ NRF_LOG_ERROR("MemManage Fault Address: 0x%08X", SCB->MMFAR);
+ }
+
+ if (cfsr & CFSR_BFARVALID)
+ {
+ NRF_LOG_ERROR("Bus Fault Address: 0x%08X", SCB->BFAR);
+ }
+
+ NRF_BREAKPOINT_COND;
+
+ #endif // defined (DEBUG)
+
+#endif // __CORTEX_M == 0x04
+
+ HardFault_process((HardFault_stack_t *)p_stack_address);
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c
new file mode 100644
index 0000000..85db240
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+extern void HardFault_c_handler(uint32_t *);
+
+void HardFault_Handler(void) __attribute__(( naked ));
+
+void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " .syntax unified \n"
+
+ " ldr r0, =0xFFFFFFFD \n"
+ " cmp r0, lr \n"
+ " bne HardFault_Handler_ChooseMSP \n"
+ /* Reading PSP into R0 */
+ " mrs r0, PSP \n"
+ " b HardFault_Handler_Continue \n"
+ "HardFault_Handler_ChooseMSP: \n"
+ /* Reading MSP into R0 */
+ " mrs r0, MSP \n"
+ /* -----------------------------------------------------------------
+ * If we have selected MSP check if we may use stack safetly.
+ * If not - reset the stack to the initial value. */
+ " ldr r1, =__StackTop \n"
+ " ldr r2, =__StackLimit \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi HardFault_MoveSP \n"
+ " cmp r0, r2 \n"
+ " bhi HardFault_Handler_Continue \n"
+ /* ----------------------------------------------------------------- */
+ "HardFault_MoveSP: \n"
+ " mov SP, r1 \n"
+ " movs r0, #0 \n"
+
+ "HardFault_Handler_Continue: \n"
+ " ldr r3, =%0 \n"
+ " bx r3 \n"
+
+ " .ltorg \n"
+ : : "X"(HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c
new file mode 100644
index 0000000..6c4e5a2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+#pragma section = "CSTACK"
+extern void HardFault_c_handler( uint32_t * );
+
+__stackless void HardFault_Handler(void);
+
+__stackless void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " ldr r0, 100f \n"
+ " cmp r0, lr \n"
+ " bne 1f \n"
+ /* Reading PSP into R0 */
+ " mrs r0, PSP \n"
+ " b 3f \n"
+ "1: \n"
+ /* Reading MSP into R0 */
+ " mrs r0, MSP \n"
+ /* -----------------------------------------------------------------
+ * If we have selected MSP check if we may use stack safetly.
+ * If not - reset the stack to the initial value. */
+ " ldr r1, 101f \n"
+ " ldr r2, 102f \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi 2f \n"
+ " cmp r0, r2 \n"
+ " bhi 3f \n"
+ /* ----------------------------------------------------------------- */
+ "2: \n"
+ " mov SP, r1 \n"
+ " movs r0, #0 \n"
+
+ "3: \n"
+ " ldr r3, 103f \n"
+ " bx r3 \n"
+
+ "DATA \n"
+ "100: \n"
+ " DC32 0xFFFFFFFD \n"
+ "101: \n"
+ " DC32 %c0 \n"
+ "102: \n"
+ " DC32 %c1 \n"
+ "103: \n"
+ " DC32 %c2 \n"
+ : /* Outputs */
+ : /* Inputs */
+ "i"(__section_end("CSTACK")),
+ "i"(__section_begin("CSTACK")),
+ "i"(&HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c
new file mode 100644
index 0000000..a1dcd3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+
+//lint -save -e27
+
+__ASM void HardFault_Handler(void)
+{
+ PRESERVE8
+ EXTERN HardFault_c_handler
+ EXTERN |STACK$$Base|
+ EXTERN |STACK$$Limit|
+
+ ldr r0, =0xFFFFFFFD
+ cmp r0, lr
+ bne HardFault_Handler_ChooseMSP
+ /* Reading PSP into R0 */
+ mrs r0, PSP
+ b HardFault_Handler_Continue
+HardFault_Handler_ChooseMSP
+ /* Reading MSP into R0 */
+ mrs r0, MSP
+ /* -----------------------------------------------------------------
+ * If we have selected MSP, check if we may use stack safely.
+ * If not - reset the stack to the initial value. */
+ ldr r1, =|STACK$$Limit|
+ ldr r2, =|STACK$$Base|
+
+ /* MSP is in the range of the stack area */
+ cmp r0, r1
+ bhi HardFault_MoveSP
+ cmp r0, r2
+ bhi HardFault_Handler_Continue
+ /* ----------------------------------------------------------------- */
+HardFault_MoveSP
+ mov SP, r1
+ movs r0, #0
+
+HardFault_Handler_Continue
+ ldr r3, =HardFault_c_handler
+ bx r3
+
+ ALIGN
+}
+
+//lint -restore
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c
new file mode 100644
index 0000000..13d5a1b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+extern void HardFault_c_handler(uint32_t *);
+
+void HardFault_Handler(void) __attribute__(( naked ));
+
+void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " tst lr, #4 \n"
+
+ /* PSP is quite simple and does not require additional handler */
+ " itt ne \n"
+ " mrsne r0, psp \n"
+ /* Jump to the handler, do not store LR - returning from handler just exits exception */
+ " bne HardFault_Handler_Continue \n"
+
+ /* Processing MSP requires stack checking */
+ " mrs r0, msp \n"
+
+ " ldr r1, =__StackTop \n"
+ " ldr r2, =__StackLimit \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi HardFault_MoveSP \n"
+ " cmp r0, r2 \n"
+ " bhi HardFault_Handler_Continue \n"
+
+ "HardFault_MoveSP: \n"
+ " mov sp, r1 \n"
+ " mov r0, #0 \n"
+
+ "HardFault_Handler_Continue: \n"
+#if HARDFAULT_HANDLER_GDB_PSP_BACKTRACE
+ " mov r3, sp \n" /* Remember old SP */
+ " mov sp, r0 \n" /* SP changed the pointer when hardfault was generated - we cannot just switch to PSP in exception */
+ " push {r3,lr} \n" /* Save old SP and LR on the task stack */
+#if !defined(__SES_ARM)
+ " .cfi_def_cfa_offset 8 \n"
+ " .cfi_offset 14, -4 \n"
+#endif
+ /* No information about saved SP above (no .cfi_offset 13, -8).
+ * In other case this would direct us back to using always MSP while backtracking */
+ " ldr r3, =%0 \n"
+ " blx r3 \n"
+ " pop {r3,lr} \n"
+ " mov sp, r3 \n"
+ " bx lr \n"
+#else // HARDFAULT_HANDLER_GDB_PSP_BACKTRACE
+ " ldr r3, =%0 \n"
+ " bx r3 \n"
+#endif
+ " .ltorg \n"
+ : : "X"(HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c
new file mode 100644
index 0000000..03a40bf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+#pragma section = "CSTACK"
+extern void HardFault_c_handler( uint32_t * );
+
+__stackless void HardFault_Handler(void);
+
+__stackless void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " ldr.n r3, 103f \n"
+ " tst lr, #4 \n"
+
+ /* PSP is quite simple and does not require additional handler */
+ " itt ne \n"
+ " mrsne r0, psp \n"
+ /* Jump to the handler, do not store LR - returning from handler just exits exception */
+ " bxne r3 \n"
+
+ /* Processing MSP requires stack checking */
+ " mrs r0, msp \n"
+
+ " ldr.n r1, 101f \n"
+ " ldr.n r2, 102f \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi.n 1f \n"
+ " cmp r0, r2 \n"
+ " bhi.n 2f \n"
+
+ "1: \n"
+ " mov sp, r1 \n"
+ " mov r0, #0 \n"
+
+ "2: \n"
+ " bx r3 \n"
+ /* Data alignment if required */
+ " nop \n"
+
+ "DATA \n"
+ "101: \n"
+ " DC32 %c0 \n"
+ "102: \n"
+ " DC32 %c1 \n"
+ "103: \n"
+ " DC32 %c2 \n"
+ : /* Outputs */
+ : /* Inputs */
+ "i"(__section_end("CSTACK")),
+ "i"(__section_begin("CSTACK")),
+ "i"(&HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c
new file mode 100644
index 0000000..2752489
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+
+//lint -save -e27
+
+__ASM void HardFault_Handler(void)
+{
+ PRESERVE8
+ EXTERN HardFault_c_handler
+ EXTERN |STACK$$Base|
+ EXTERN |STACK$$Limit|
+
+ ldr r3, =HardFault_c_handler
+ tst lr, #4
+
+ /* PSP is quite simple and does not require additional handler */
+ itt ne
+ mrsne r0, psp
+ /* Jump to the handler, do not store LR - returning from handler just exits exception */
+ bxne r3
+
+ /* Processing MSP requires stack checking */
+ mrs r0, msp
+
+ ldr r1, =|STACK$$Limit|
+ ldr r2, =|STACK$$Base|
+
+ /* MSP is in the range of the stack area */
+ cmp r0, r1
+ bhi HardFault_MoveSP
+ cmp r0, r2
+ bhi HardFault_Handler_Continue
+
+HardFault_MoveSP
+ mov sp, r1
+ mov r0, #0
+
+HardFault_Handler_Continue
+ bx r3
+
+ ALIGN
+}
+
+//lint -restore
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c
new file mode 100644
index 0000000..ec97aa6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c
@@ -0,0 +1,264 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HCI_MEM_POOL)
+#include "hci_mem_pool.h"
+#include <stdbool.h>
+#include <stdio.h>
+
+/**@brief RX buffer element instance structure.
+ */
+typedef struct
+{
+ uint8_t rx_buffer[HCI_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[HCI_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 = HCI_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[HCI_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 <= HCI_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) & (HCI_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) &
+ (HCI_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) & (HCI_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) & (HCI_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) & (HCI_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) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
+
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+
+ return err_code;
+}
+#endif //NRF_MODULE_ENABLED(HCI_MEM_POOL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h
new file mode 100644
index 0000000..9b1bf7e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup hci_mem_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.svg "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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@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);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HCI_MEM_POOL_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c
new file mode 100644
index 0000000..ab70b82
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c
@@ -0,0 +1,457 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HCI_SLIP)
+#include "hci_slip.h"
+#include <stdlib.h>
+#include "app_uart.h"
+#include "nrf_error.h"
+
+#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
+#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
+#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
+#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
+
+/** @brief States for the SLIP state machine. */
+typedef enum
+{
+ SLIP_OFF, /**< SLIP state OFF. */
+ SLIP_READY, /**< SLIP state ON. */
+ SLIP_TRANSMITTING, /**< SLIP state is transmitting indicating write() has been called but data transmission has not completed. */
+} slip_states_t;
+
+static slip_states_t m_current_state = SLIP_OFF; /** Current state for the SLIP TX state machine. */
+
+static hci_slip_event_handler_t m_slip_event_handler; /** Event callback function for handling of SLIP events, @ref hci_slip_evt_type_t . */
+
+static const uint8_t * mp_tx_buffer; /** Pointer to the current TX buffer that is in transmission. */
+static uint32_t m_tx_buffer_length; /** Length of the current TX buffer that is in transmission. */
+static volatile uint32_t m_tx_buffer_index; /** Current index for next byte to transmit in the mp_tx_buffer. */
+
+static uint8_t * mp_rx_buffer; /** Pointer to the current RX buffer where the next SLIP decoded packet will be stored. */
+static uint32_t m_rx_buffer_length; /** Length of the current RX buffer. */
+static uint32_t m_rx_received_count; /** Number of SLIP decoded bytes received and stored in mp_rx_buffer. */
+
+
+/**@brief Function for parsing bytes received on the UART until a SLIP escape byte is received.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void handle_rx_byte_default(uint8_t byte);
+
+/**@brief Function for parsing bytes received on the UART until SLIP end byte is received.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void handle_rx_byte_wait_start(uint8_t byte);
+
+/**@brief Function for decoding a received SLIP escape byte.
+ * It will ensure correct decoding of the byte following the SLIP escape byte.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void handle_rx_byte_esc(uint8_t byte);
+
+/**@brief Function pointer for parsing and decoding SLIP bytes from the UART module.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void (*handle_rx_byte) (uint8_t byte) = handle_rx_byte_wait_start;
+
+/**@brief Function pointer for sending a byte through the UART module.
+ */
+static uint32_t send_tx_byte_default(void);
+
+/**@brief Function for transferring a SLIP escape byte (0xDB) when special bytes are transferred,
+ * that is 0xC0 and 0xDB.
+ */
+static uint32_t send_tx_byte_esc(void);
+
+/**@brief Function for transferring a byte when it collides with SLIP commands and follows the SLIP
+ * escape byte, that is 0xC0 => 0xDC and 0xDB => 0xDD.
+ */
+static uint32_t send_tx_byte_encoded(void);
+
+/**@brief Function for transferring the SLIP end frame byte, 0xC0.
+ */
+static uint32_t send_tx_byte_end(void);
+
+/**@brief Function pointer for sending a byte through the UART module.
+ */
+uint32_t (*send_tx_byte) (void) = send_tx_byte_default;
+
+
+static uint32_t send_tx_byte_end(void)
+{
+ uint32_t err_code = app_uart_put(APP_SLIP_END);
+
+ if ((err_code == NRF_SUCCESS) && (m_tx_buffer_index == 0))
+ {
+ // Packet transmission started.
+ send_tx_byte = send_tx_byte_default;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t send_tx_byte_default(void)
+{
+ uint32_t err_code = app_uart_put(mp_tx_buffer[m_tx_buffer_index]);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_tx_buffer_index++;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t send_tx_byte_encoded(void)
+{
+ uint32_t err_code;
+
+ switch (mp_tx_buffer[m_tx_buffer_index])
+ {
+ case APP_SLIP_END:
+ err_code = app_uart_put(APP_SLIP_ESC_END);
+ break;
+
+ case APP_SLIP_ESC:
+ err_code = app_uart_put(APP_SLIP_ESC_ESC);
+ break;
+
+ default:
+ err_code = NRF_ERROR_NO_MEM;
+ break;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_tx_buffer_index++;
+ send_tx_byte = send_tx_byte_default;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t send_tx_byte_esc(void)
+{
+ uint32_t err_code = app_uart_put(APP_SLIP_ESC);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ send_tx_byte = send_tx_byte_encoded;
+ }
+
+ return err_code;
+}
+
+
+/** @brief Function for transferring the content of the mp_tx_buffer to the UART.
+ * It continues to transfer bytes until the UART buffer is full or the complete buffer is
+ * transferred.
+ */
+static void transmit_buffer(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ while (m_tx_buffer_index < m_tx_buffer_length)
+ {
+ if ((mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_END ||
+ mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_ESC) &&
+ send_tx_byte == send_tx_byte_default)
+ {
+ send_tx_byte = send_tx_byte_esc;
+ }
+
+ err_code = send_tx_byte();
+
+ if (err_code == NRF_ERROR_NO_MEM || err_code == NRF_ERROR_BUSY)
+ {
+ // No memory left in UART TX buffer. Abort and wait for APP_UART_TX_EMPTY to continue.
+ return;
+ }
+ }
+
+ send_tx_byte = send_tx_byte_end;
+
+ err_code = send_tx_byte();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Packet transmission ended. Notify higher level.
+ m_current_state = SLIP_READY;
+
+ if (m_slip_event_handler != NULL)
+ {
+ hci_slip_evt_t event = {HCI_SLIP_TX_DONE, mp_tx_buffer, m_tx_buffer_index};
+
+ m_slip_event_handler(event);
+ }
+ }
+}
+
+
+/** @brief Function for handling the reception of a SLIP end byte.
+ * If the number of bytes received is greater than zero it will call m_slip_event_handler
+ * with number of bytes received and invalidate the mp_rx_buffer to protect against data
+ * corruption.
+ * No new bytes can be received until a new RX buffer is supplied.
+ */
+static void handle_slip_end(void)
+{
+ if (m_rx_received_count > 0)
+ {
+ // Full packet received, push it up.
+ if (m_slip_event_handler != NULL)
+ {
+ hci_slip_evt_t event = {HCI_SLIP_RX_RDY, mp_rx_buffer, m_rx_received_count};
+
+ m_rx_received_count = 0;
+ mp_rx_buffer = NULL;
+
+ m_slip_event_handler(event);
+ }
+ }
+}
+
+
+static void handle_rx_byte_esc(uint8_t byte)
+{
+ switch (byte)
+ {
+ case APP_SLIP_END:
+ handle_slip_end();
+ break;
+
+ case APP_SLIP_ESC_END:
+ mp_rx_buffer[m_rx_received_count++] = APP_SLIP_END;
+ break;
+
+ case APP_SLIP_ESC_ESC:
+ mp_rx_buffer[m_rx_received_count++] = APP_SLIP_ESC;
+ break;
+
+ default:
+ mp_rx_buffer[m_rx_received_count++] = byte;
+ break;
+ }
+
+ handle_rx_byte = handle_rx_byte_default;
+}
+
+
+static void handle_rx_byte_default(uint8_t byte)
+{
+ switch (byte)
+ {
+ case APP_SLIP_END:
+ handle_slip_end();
+ break;
+
+ case APP_SLIP_ESC:
+ handle_rx_byte = handle_rx_byte_esc;
+ break;
+
+ default:
+ mp_rx_buffer[m_rx_received_count++] = byte;
+ break;
+ }
+}
+
+
+static void handle_rx_byte_wait_start(uint8_t byte)
+{
+ if (byte == APP_SLIP_END)
+ {
+ handle_rx_byte = handle_rx_byte_default;
+ }
+}
+
+
+/** @brief Function for checking the current index and length of the RX buffer to determine if the
+ * buffer is full. If an event handler has been registered, the callback function will
+ * be executed..
+ *
+ * @retval true If RX buffer has overflowed.
+ * @retval false otherwise.
+ *
+ */
+static bool rx_buffer_overflowed(void)
+{
+ if (mp_rx_buffer == NULL || m_rx_received_count >= m_rx_buffer_length)
+ {
+ if (m_slip_event_handler != NULL)
+ {
+ hci_slip_evt_t event = {HCI_SLIP_RX_OVERFLOW, mp_rx_buffer, m_rx_received_count};
+ m_slip_event_handler(event);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+/** @brief Function for handling the UART module event. It parses events from the UART when
+ * bytes are received/transmitted.
+ *
+ * @param[in] uart_event Event received from app_uart module.
+ */
+static void slip_uart_eventhandler(app_uart_evt_t * uart_event)
+{
+ if (uart_event->evt_type == APP_UART_TX_EMPTY && m_current_state == SLIP_TRANSMITTING)
+ {
+ transmit_buffer();
+ }
+
+ if ((uart_event->evt_type == APP_UART_DATA) && (!rx_buffer_overflowed()))
+ {
+ handle_rx_byte(uart_event->data.value);
+ }
+}
+
+
+/** @brief Function for enabling the UART module when the SLIP layer is opened.
+ */
+static uint32_t slip_uart_open(void)
+{
+ uint32_t err_code;
+
+ app_uart_comm_params_t comm_params =
+ {
+ HCI_UART_RX_PIN,
+ HCI_UART_TX_PIN,
+ HCI_UART_RTS_PIN,
+ HCI_UART_CTS_PIN,
+ (app_uart_flow_control_t)HCI_UART_FLOW_CONTROL,
+ false,
+ HCI_UART_BAUDRATE
+ };
+
+ err_code = app_uart_init(&comm_params,
+ NULL,
+ slip_uart_eventhandler,
+ APP_IRQ_PRIORITY_LOWEST);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_current_state = SLIP_READY;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler)
+{
+ m_slip_event_handler = event_handler;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_slip_open()
+{
+ switch (m_current_state)
+ {
+ case SLIP_OFF:
+ return slip_uart_open();
+
+ default:
+ // Do nothing.
+ break;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_slip_close()
+{
+ m_current_state = SLIP_OFF;
+ uint32_t err_code = app_uart_close();
+
+ return err_code;
+}
+
+
+uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ switch (m_current_state)
+ {
+ case SLIP_READY:
+ m_tx_buffer_index = 0;
+ m_tx_buffer_length = length;
+ mp_tx_buffer = p_buffer;
+ m_current_state = SLIP_TRANSMITTING;
+ send_tx_byte = send_tx_byte_end;
+
+ transmit_buffer();
+ return NRF_SUCCESS;
+
+ case SLIP_TRANSMITTING:
+ return NRF_ERROR_NO_MEM;
+
+ case SLIP_OFF:
+ default:
+ return NRF_ERROR_INVALID_STATE;
+ }
+}
+
+
+uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length)
+{
+ mp_rx_buffer = p_buffer;
+ m_rx_buffer_length = length;
+ m_rx_received_count = 0;
+ handle_rx_byte = handle_rx_byte_wait_start;
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(HCI_SLIP)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h
new file mode 100644
index 0000000..7741319
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup hci_slip SLIP module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief SLIP layer for supporting packet framing in HCI transport.
+ *
+ * @details This module implements SLIP packet framing as described in the Bluetooth Core
+ * Specification 4.0, Volume 4, Part D, Chapter 3 SLIP Layer.
+ *
+ * SLIP framing ensures that all packets sent on the UART are framed as:
+ * <0xC0> SLIP packet 1 <0xC0> <0xC0> SLIP packet 2 <0xC0>.
+ *
+ * The SLIP layer uses events to notify the upper layer when data transmission is complete
+ * and when a SLIP packet is received.
+ */
+
+#ifndef HCI_SLIP_H__
+#define HCI_SLIP_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Event types from the SLIP Layer. */
+typedef enum
+{
+ HCI_SLIP_RX_RDY, /**< An event indicating that an RX packet is ready to be read. */
+ HCI_SLIP_TX_DONE, /**< An event indicating write completion of the TX packet provided in the function call \ref hci_slip_write . */
+ HCI_SLIP_RX_OVERFLOW, /**< An event indicating that RX data has been discarded due to lack of free RX memory. */
+ HCI_SLIP_ERROR, /**< An event indicating that an unrecoverable error has occurred. */
+ HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} hci_slip_evt_type_t;
+
+/**@brief Structure containing an event from the SLIP layer.
+ */
+typedef struct
+{
+ hci_slip_evt_type_t evt_type; /**< Type of event. */
+ const uint8_t * packet; /**< This field contains a pointer to the packet for which the event relates, i.e. SLIP_TX_DONE: the packet transmitted, SLIP_RX_RDY: the packet received, SLIP_RX_OVERFLOW: The packet which overflow/or NULL if no receive buffer is available. */
+ uint32_t packet_length; /**< Packet length, i.e. SLIP_TX_DONE: Bytes transmitted, SLIP_RX_RDY: Bytes received, SLIP_RX_OVERFLOW: index at which the packet overflowed. */
+} hci_slip_evt_t;
+
+/**@brief Function for the SLIP layer event callback.
+ */
+typedef void (*hci_slip_event_handler_t)(hci_slip_evt_t event);
+
+/**@brief Function for registering the event handler provided as parameter and this event handler
+ * will be used by SLIP layer to send events described in \ref hci_slip_evt_type_t.
+ *
+ * @note Multiple registration requests will overwrite any existing registration.
+ *
+ * @param[in] event_handler This function is called by the SLIP layer upon an event.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler);
+
+/**@brief Function for opening the SLIP layer. This function must be called before
+ * \ref hci_slip_write and before any data can be received.
+ *
+ * @note Can be called multiple times.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ *
+ * The SLIP layer module will propagate errors from underlying sub-modules.
+ * This implementation is using UART module as a physical transmission layer, and hci_slip_open
+ * executes \ref app_uart_init . For an extended error list, please refer to \ref app_uart_init .
+ */
+uint32_t hci_slip_open(void);
+
+/**@brief Function for closing the SLIP layer. After this function is called no data can be
+ * transmitted or received in this layer.
+ *
+ * @note This function can be called multiple times and also for an unopened channel.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_slip_close(void);
+
+/**@brief Function for writing a packet with SLIP encoding. Packet transmission is confirmed when
+ * the HCI_SLIP_TX_DONE event is received by the function caller.
+ *
+ * @param[in] p_buffer Pointer to the packet to transmit.
+ * @param[in] length Packet length, in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was encoded and added to the
+ * transmission queue and an event will be sent upon transmission
+ * completion.
+ * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not
+ * added to the transmission queue. Application shall wait for
+ * the \ref HCI_SLIP_TX_DONE event. After HCI_SLIP_TX_DONE this
+ * function can be executed for transmission of next packet.
+ * @retval NRF_ERROR_INVALID_ADDR If a NULL pointer is provided.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Module is not open.
+ */
+uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length);
+
+/**@brief Function for registering a receive buffer. The receive buffer will be used for storage of
+ * received and SLIP decoded data.
+ * No data can be received by the SLIP layer until a receive buffer has been registered.
+ *
+ * @note The lifetime of the buffer must be valid during complete reception of data. A static
+ * buffer is recommended.
+ *
+ * @warning Multiple registration requests will overwrite any existing registration.
+ *
+ * @param[in] p_buffer Pointer to receive buffer. The received and SLIP decoded packet
+ * will be placed in this buffer.
+ * @param[in] length Buffer length, in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HCI_SLIP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c
new file mode 100644
index 0000000..f4d6c02
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c
@@ -0,0 +1,808 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HCI_TRANSPORT)
+#include "hci_transport.h"
+#include "hci_slip.h"
+#include "crc16.h"
+#include "hci_mem_pool.h"
+#include "app_timer.h"
+#include "app_error.h"
+#include <stdio.h>
+
+#define PKT_HDR_SIZE 4u /**< Packet header size in number of bytes. */
+#define PKT_CRC_SIZE 2u /**< Packet CRC size in number of bytes. */
+#define PKT_TYPE_VENDOR_SPECIFIC 14u /**< Packet type vendor specific. */
+#define PKT_TYPE_ACK 0 /**< Packet type acknowledgement. */
+#define DATA_INTEGRITY_MASK (1u << 6u) /**< Mask for data integrity bit in the packet header. */
+#define RELIABLE_PKT_MASK (1u << 7u) /**< Mask for reliable packet bit in the packet header. */
+#define INITIAL_ACK_NUMBER_EXPECTED 1u /**< Initial acknowledge number expected. */
+#define INITIAL_ACK_NUMBER_TX INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */
+#define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */
+#define HCI_UART_REG_VALUE_TO_BAUDRATE(BAUDRATE) ((BAUDRATE)/268) /**< Estimated relation between UART baudrate register value and actual baudrate */
+#define MAX_TRANSMISSION_TIME \
+ (ROUNDED_DIV((HCI_MAX_PACKET_SIZE_IN_BITS * 1000u), \
+ HCI_UART_REG_VALUE_TO_BAUDRATE(HCI_UART_BAUDRATE))) /**< Max transmission time of a single application packet over UART in units of mseconds. */
+#define RETRANSMISSION_TIMEOUT_IN_MS (3u * MAX_TRANSMISSION_TIME) /**< Retransmission timeout for application packet in units of mseconds. */
+#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS) /**< Retransmission timeout for application packet in units of timer ticks. */
+#define MAX_RETRY_COUNT 5u /**< Max retransmission retry count for application packets. */
+#define ACK_BUF_SIZE 5u /**< Length of module internal RX buffer which is big enough to hold an acknowledgement packet. */
+
+/**@brief States of the TX state machine. */
+typedef enum
+{
+ TX_STATE_IDLE, /**< State for: no application transmission packet processing in progress. */
+ TX_STATE_PENDING, /**< State for: TX in progress in slip layer and TX-done event is waited for to signal the end of transmission. */
+ TX_STATE_ACTIVE /**< State for: application packet has been delivered to slip for transmission and peer transport entity acknowledgement packet is waited for. */
+} tx_state_t;
+
+/**@brief TX state machine events. */
+typedef enum
+{
+ TX_EVENT_STATE_ENTRY, /**< Event for: state entry use case. */
+ TX_EVENT_SLIP_TX_DONE, /**< Event for: HCI_SLIP_TX_DONE event use case. */
+ TX_EVENT_TIMEOUT, /**< Event for: retransmission timeout use case. */
+ TX_EVENT_VALID_RX_ACK /**< Event for: valid acknowledgement received for TX packet use case. */
+} tx_event_t;
+
+static void tx_sm_state_change(tx_state_t new_state);
+
+static tx_state_t m_tx_state; /**< Current TX state. */
+static hci_transport_tx_done_handler_t m_transport_tx_done_handle; /**< TX done event callback function. */
+static hci_transport_event_handler_t m_transport_event_handle; /**< Event handler callback function. */
+static uint8_t * mp_slip_used_rx_buffer; /**< Reference to RX buffer used by the slip layer. */
+static uint32_t m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */
+static uint32_t m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */
+static uint8_t * mp_tx_buffer; /**< Pointer to TX application buffer to be transmitted. */
+static uint32_t m_tx_buffer_length; /**< Length of application TX packet data to be transmitted in bytes. */
+static bool m_is_slip_decode_ready; /**< Boolean to determine has slip decode been completed or not. */
+APP_TIMER_DEF(m_app_timer_id); /**< Application timer id. */
+static uint32_t m_tx_retry_counter; /**< Application packet retransmission counter. */
+static hci_transport_tx_done_result_t m_tx_done_result_code; /**< TX done event callback function result code. */
+static uint8_t m_rx_ack_buffer[ACK_BUF_SIZE];/**< RX buffer big enough to hold an acknowledgement packet and which is taken in use upon receiving HCI_SLIP_RX_OVERFLOW event. */
+
+
+/**@brief Function for validating a received packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return true if received packet is valid, false in other case.
+ */
+static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
+{
+ // Executed packet filtering algorithm order:
+ // - verify packet overall length
+ // - verify data integrity bit set
+ // - verify reliable packet bit set
+ // - verify supported packet type
+ // - verify header checksum
+ // - verify payload length field
+ // - verify CRC
+ if (length <= PKT_HDR_SIZE)
+ {
+ return false;
+ }
+
+ if (!(p_buffer[0] & DATA_INTEGRITY_MASK))
+ {
+ return false;
+ }
+
+ if (!(p_buffer[0] & RELIABLE_PKT_MASK))
+ {
+ return false;
+ }
+
+ if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC)
+ {
+ return false;
+ }
+
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+ if (expected_checksum != 0)
+ {
+ return false;
+ }
+
+ const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL);
+ const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]);
+ if (crc_calculated != crc_received)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@brief Function for getting the sequence number of the next reliable packet expected.
+ *
+ * @return sequence number of the next reliable packet expected.
+ */
+static __INLINE uint8_t packet_number_expected_get(void)
+{
+ return (uint8_t) m_packet_expected_seq_number;
+}
+
+
+/**@brief Function for calculating a packet header checksum.
+ *
+ * @param[in] p_hdr Pointer to the packet header.
+ *
+ * @return Calculated checksum.
+ */
+static uint8_t header_checksum_calculate(const uint8_t * p_hdr)
+{
+ // @note: no pointer validation check needed as already checked by calling function.
+ uint32_t checksum;
+
+ checksum = p_hdr[0];
+ checksum += p_hdr[1];
+ checksum += p_hdr[2];
+ checksum &= 0xFFu;
+ checksum = (~checksum + 1u);
+
+ return (uint8_t)checksum;
+}
+
+
+/**@brief Function for writing an acknowledgment packet for transmission.
+ */
+static void ack_transmit(void)
+{
+ static uint8_t ack_packet[PKT_HDR_SIZE];
+
+ // TX ACK packet format:
+ // - Unreliable Packet type
+ // - Payload Length set to 0
+ // - Sequence Number set to 0
+ // - Header checksum calculated
+ // - Acknowledge Number set correctly
+ ack_packet[0] = (packet_number_expected_get() << 3u);
+ ack_packet[1] = 0;
+ ack_packet[2] = 0;
+ ack_packet[3] = header_checksum_calculate(ack_packet);
+
+ // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets
+ // are considered to be from system design point of view unreliable packets.Use case where
+ // underlying slip layer does not accept a packet for transmission is managed either by:
+ // - acknowledged by possible future application packet as acknowledgement number header field
+ // is included
+ // - protocol peer entity will retransmit the packet
+ UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet)));
+}
+
+
+/**@brief Function for validating a received packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ *
+ * @return sequence number field of the packet header with unrelated data masked out.
+ */
+static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer)
+{
+ return (p_buffer[0] & 0x07u);
+}
+
+
+/**@brief Function for incrementing the sequence number counter for next reliable packet expected.
+ */
+static __INLINE void packet_number_expected_inc(void)
+{
+ ++m_packet_expected_seq_number;
+ m_packet_expected_seq_number &= 0x07u;
+}
+
+
+/**@brief Function for decoding a packet type field.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return Packet type field or INVALID_PKT_TYPE in case of decode error.
+ */
+static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+ uint32_t return_value;
+
+ if (length >= PKT_HDR_SIZE)
+ {
+ return_value = (p_buffer[1] & 0x0Fu);
+ }
+ else
+ {
+ return_value = INVALID_PKT_TYPE;
+ }
+
+ return return_value;
+}
+
+
+/**@brief Function for processing a received vendor specific packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ */
+static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+ uint32_t err_code;
+
+ if (is_rx_pkt_valid(p_buffer, length))
+ {
+ // RX packet is valid: validate sequence number.
+ const uint8_t rx_seq_number = packet_seq_nmbr_extract(p_buffer);
+ if (packet_number_expected_get() == rx_seq_number)
+ {
+ // Sequence number is valid: transmit acknowledgement.
+ packet_number_expected_inc();
+ ack_transmit();
+
+ m_is_slip_decode_ready = true;
+
+ err_code = hci_mem_pool_rx_data_size_set(length);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
+ APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
+
+ // If memory pool RX buffer produce succeeded we register that buffer to slip layer
+ // otherwise we register the internal acknowledgement buffer.
+ err_code = hci_slip_rx_buffer_register(
+ (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
+ (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
+
+ APP_ERROR_CHECK(err_code);
+
+ if (m_transport_event_handle != NULL)
+ {
+ // Send application event of RX packet reception.
+ const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY};
+ m_transport_event_handle(evt);
+ }
+ }
+ else
+ {
+ // RX packet discarded: sequence number not valid, set the same buffer to slip layer in
+ // order to avoid buffer overrun.
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+
+ // As packet did not have expected sequence number: send acknowledgement with the
+ // current expected sequence number.
+ ack_transmit();
+ }
+ }
+ else
+ {
+ // RX packet discarded: reset the same buffer to slip layer in order to avoid buffer
+ // overrun.
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol
+ * entity acknowledgment is pending.
+ *
+ * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement
+ * is pending.
+ */
+static __INLINE uint8_t packet_number_to_transmit_get(void)
+{
+ return m_packet_transmit_seq_number;
+}
+
+
+/**@brief Function for getting the expected acknowledgement number.
+ *
+ * @return expected acknowledgement number.
+ */
+static __INLINE uint8_t expected_ack_number_get(void)
+{
+ uint8_t seq_nmbr = packet_number_to_transmit_get();
+ ++seq_nmbr;
+ seq_nmbr &= 0x07u;
+
+ return seq_nmbr;
+}
+
+
+/**@brief Function for processing a received acknowledgement packet.
+ *
+ * Verifies does the received acknowledgement packet has the expected acknowledgement number and
+ * that the header checksum is correct.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ *
+ * @return true if valid acknowledgement packet received.
+ */
+static __INLINE bool rx_ack_pkt_type_handle(const uint8_t * p_buffer)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+
+ // Verify header checksum.
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+ if (expected_checksum != 0)
+ {
+ return false;
+ }
+
+ const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u;
+
+ // Verify expected acknowledgment number.
+ return (ack_number == expected_ack_number_get());
+}
+
+
+/**@brief Function for incrementing the sequence number counter of the TX packet.
+ */
+static __INLINE void packet_number_tx_inc(void)
+{
+ ++m_packet_transmit_seq_number;
+ m_packet_transmit_seq_number &= 0x07u;
+}
+
+
+/**@brief Function for TX state machine event processing in a state centric manner.
+ *
+ * @param[in] event Type of event occurred.
+ */
+static void tx_sm_event_handle(tx_event_t event)
+{
+ uint32_t err_code;
+
+ switch (m_tx_state)
+ {
+ case TX_STATE_IDLE:
+ if (event == TX_EVENT_STATE_ENTRY)
+ {
+ err_code = app_timer_stop(m_app_timer_id);
+ APP_ERROR_CHECK(err_code);
+
+ // Send TX-done event if registered handler exists.
+ if (m_transport_tx_done_handle != NULL)
+ {
+ m_transport_tx_done_handle(m_tx_done_result_code);
+ }
+ }
+ break;
+
+ case TX_STATE_PENDING:
+ if (event == TX_EVENT_SLIP_TX_DONE)
+ {
+ // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context
+ // and error cases are managed by dedicated error event from the slip layer.
+ err_code = hci_slip_write(mp_tx_buffer,
+ (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
+ APP_ERROR_CHECK(err_code);
+ tx_sm_state_change(TX_STATE_ACTIVE);
+ }
+ break;
+
+ case TX_STATE_ACTIVE:
+ switch (event)
+ {
+ case TX_EVENT_VALID_RX_ACK:
+ // Tx sequence number counter incremented as packet transmission
+ // acknowledged by peer transport entity.
+ packet_number_tx_inc();
+ tx_sm_state_change(TX_STATE_IDLE);
+ break;
+
+ case TX_EVENT_STATE_ENTRY:
+ m_tx_retry_counter = 0;
+ err_code = app_timer_start(m_app_timer_id,
+ RETRANSMISSION_TIMEOUT_IN_TICKS,
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ case TX_EVENT_TIMEOUT:
+ if (m_tx_retry_counter != MAX_RETRY_COUNT)
+ {
+ ++m_tx_retry_counter;
+ // @note: no return value check done for hci_slip_write(...) call as current
+ // system design allows use case where retransmission is not accepted by the
+ // slip layer due to existing acknowledgement packet transmission in the
+ // slip layer.
+ UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer,
+ (m_tx_buffer_length +
+ PKT_HDR_SIZE +
+ PKT_CRC_SIZE)));
+ }
+ else
+ {
+ // Application packet retransmission count reached:
+ // - set correct TX done event callback function result code
+ // - execute state change
+ // @note: m_tx_retry_counter is reset in TX_STATE_ACTIVE state entry.
+ m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
+ tx_sm_state_change(TX_STATE_IDLE);
+ }
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for changing the state of the TX state machine.
+ *
+ * @param[in] new_state State TX state machine transits to.
+ */
+static void tx_sm_state_change(tx_state_t new_state)
+{
+ m_tx_state = new_state;
+ tx_sm_event_handle(TX_EVENT_STATE_ENTRY);
+}
+
+
+/**@brief Function for handling slip events.
+ *
+ * @param[in] event The event structure.
+ */
+void slip_event_handle(hci_slip_evt_t event)
+{
+ uint32_t return_code;
+ uint32_t err_code;
+
+ switch (event.evt_type)
+ {
+ case HCI_SLIP_TX_DONE:
+ tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE);
+ break;
+
+ case HCI_SLIP_RX_RDY:
+ return_code = packet_type_decode(event.packet, event.packet_length);
+
+ switch (return_code)
+ {
+ case PKT_TYPE_VENDOR_SPECIFIC:
+ rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length);
+ break;
+
+ case PKT_TYPE_ACK:
+ if (rx_ack_pkt_type_handle(event.packet))
+ {
+ // Valid expected acknowledgement packet received: set correct TX done event
+ // callback function result code and execute state change.
+ m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS;
+ tx_sm_event_handle(TX_EVENT_VALID_RX_ACK);
+ }
+
+ /* fall-through */
+ default:
+ // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer
+ // overflow.
+ // If existing mem pool produced RX buffer exists reuse that one. If existing
+ // mem pool produced RX buffer does not exist try to produce new one. If
+ // producing fails use the internal acknowledgement buffer.
+ if (mp_slip_used_rx_buffer != NULL)
+ {
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ }
+ else
+ {
+ err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE,
+ (void **)&mp_slip_used_rx_buffer);
+ APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) ||
+ (err_code == NRF_ERROR_NO_MEM));
+
+ err_code = hci_slip_rx_buffer_register(
+ (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
+ (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ }
+ break;
+ }
+ break;
+
+ case HCI_SLIP_RX_OVERFLOW:
+ err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ case HCI_SLIP_ERROR:
+ APP_ERROR_HANDLER(event.evt_type);
+ break;
+
+ default:
+ APP_ERROR_HANDLER(event.evt_type);
+ break;
+ }
+}
+
+
+uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler)
+{
+ uint32_t err_code;
+
+ m_transport_event_handle = event_handler;
+ err_code = hci_slip_evt_handler_register(slip_event_handle);
+ APP_ERROR_CHECK(err_code);
+
+ return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
+}
+
+
+uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler)
+{
+ uint32_t err_code;
+
+ m_transport_tx_done_handle = event_handler;
+ err_code = hci_slip_evt_handler_register(slip_event_handle);
+ APP_ERROR_CHECK(err_code);
+
+ return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
+}
+
+
+/**@brief Function for handling the application packet retransmission timeout.
+ *
+ * This function is registered in the @ref app_timer module when a timer is created on
+ * @ref hci_transport_open.
+ *
+ * @note This function must be executed in APP-LO context otherwise retransmission behaviour is
+ * undefined, see @ref nrf51_system_integration_serialization.
+ *
+ * @param[in] p_context The timeout context.
+ */
+void hci_transport_timeout_handle(void * p_context)
+{
+ tx_sm_event_handle(TX_EVENT_TIMEOUT);
+}
+
+
+uint32_t hci_transport_open(void)
+{
+ mp_tx_buffer = NULL;
+ m_tx_buffer_length = 0;
+ m_tx_retry_counter = 0;
+ m_is_slip_decode_ready = false;
+ m_tx_state = TX_STATE_IDLE;
+ m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED;
+ m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX;
+ m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
+
+ uint32_t err_code = app_timer_create(&m_app_timer_id,
+ APP_TIMER_MODE_REPEATED,
+ hci_transport_timeout_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ // @note: conduct required interface adjustment.
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = hci_mem_pool_open();
+ VERIFY_SUCCESS(err_code);
+
+ err_code = hci_slip_open();
+ VERIFY_SUCCESS(err_code);
+
+ err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
+ if (err_code != NRF_SUCCESS)
+ {
+ // @note: conduct required interface adjustment.
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_close(void)
+{
+ uint32_t err_code;
+
+ m_transport_tx_done_handle = NULL;
+ m_transport_event_handle = NULL;
+
+ err_code = hci_mem_pool_close();
+ APP_ERROR_CHECK(err_code);
+ err_code = hci_slip_close();
+ APP_ERROR_CHECK(err_code);
+
+ // @note: NRF_ERROR_NO_MEM is the only return value which should never be returned.
+ err_code = app_timer_stop(m_app_timer_id);
+ APP_ERROR_CHECK_BOOL(err_code != NRF_ERROR_NO_MEM);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory)
+{
+ const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory);
+ if (err_code == NRF_SUCCESS)
+ {
+ // @note: no need to validate pp_memory against null as validation has already been done
+ // by hci_mem_pool_tx_alloc(...) and visible to us from the method return code.
+ //lint -e(413) "Likely use of null pointer"
+ *pp_memory += PKT_HDR_SIZE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_tx_free(void)
+{
+ return hci_mem_pool_tx_free();
+}
+
+
+/**@brief Function for constructing 1st byte of the packet header of the packet to be transmitted.
+ *
+ * @return 1st byte of the packet header of the packet to be transmitted
+ */
+static __INLINE uint8_t tx_packet_byte_zero_construct(void)
+{
+ const uint32_t value = DATA_INTEGRITY_MASK |
+ RELIABLE_PKT_MASK |
+ (packet_number_expected_get() << 3u) |
+ packet_number_to_transmit_get();
+
+ return (uint8_t) value;
+}
+
+
+/**@brief Function for handling the application packet write request in tx-idle state.
+ */
+static uint32_t pkt_write_handle(void)
+{
+ uint32_t err_code;
+
+ // Set packet header fields.
+
+ mp_tx_buffer -= PKT_HDR_SIZE;
+ mp_tx_buffer[0] = tx_packet_byte_zero_construct();
+
+ const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC);
+ // @note: no use case for uint16_encode(...) return value.
+ UNUSED_VARIABLE(uint16_encode(type_and_length_fields, &(mp_tx_buffer[1])));
+ mp_tx_buffer[3] = header_checksum_calculate(mp_tx_buffer);
+
+ // Calculate, append CRC to the packet and write it.
+
+ const uint16_t crc = crc16_compute(mp_tx_buffer, (PKT_HDR_SIZE + m_tx_buffer_length), NULL);
+ // @note: no use case for uint16_encode(...) return value.
+ UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length])));
+ err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ tx_sm_state_change(TX_STATE_ACTIVE);
+ break;
+
+ case NRF_ERROR_NO_MEM:
+ tx_sm_state_change(TX_STATE_PENDING);
+ err_code = NRF_SUCCESS;
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t err_code;
+
+ if (p_buffer)
+ {
+ switch (m_tx_state)
+ {
+ case TX_STATE_IDLE:
+ mp_tx_buffer = (uint8_t *)p_buffer;
+ m_tx_buffer_length = length;
+ err_code = pkt_write_handle();
+ break;
+
+ default:
+ err_code = NRF_ERROR_NO_MEM;
+ break;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length)
+{
+ uint32_t err_code;
+
+ if (pp_buffer != NULL && p_length != NULL)
+ {
+ uint32_t length = 0;
+
+ if (m_is_slip_decode_ready)
+ {
+ m_is_slip_decode_ready = false;
+ err_code = hci_mem_pool_rx_extract(pp_buffer, &length);
+ length -= (PKT_HDR_SIZE + PKT_CRC_SIZE);
+
+ *p_length = (uint16_t)length;
+ *pp_buffer += PKT_HDR_SIZE;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer)
+{
+ return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE));
+}
+#endif //NRF_MODULE_ENABLED(HCI_TRANSPORT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h
new file mode 100644
index 0000000..df5df35
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup hci_transport HCI Transport
+ * @{
+ * @ingroup app_common
+ *
+ * @brief HCI transport module implementation.
+ *
+ * This module implements certain specific features from the three-wire UART transport layer,
+ * defined by the Bluetooth specification version 4.0 [Vol 4] part D.
+ *
+ * \par Features supported
+ * - Transmission and reception of Vendor Specific HCI packet type application packets.
+ * - Transmission and reception of reliable packets: defined by chapter 6 of the specification.
+ *
+ * \par Features not supported
+ * - Link establishment procedure: defined by chapter 8 of the specification.
+ * - Low power: defined by chapter 9 of the specification.
+ *
+ * \par Implementation specific behaviour
+ * - As Link establishment procedure is not supported following static link configuration parameters
+ * are used:
+ * + TX window size is 1.
+ * + 16 bit CCITT-CRC must be used.
+ * + Out of frame software flow control not supported.
+ * + Parameters specific for resending reliable packets are compile time configurable (clarifed
+ * later in this document).
+ * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for
+ * transmission within same context which the corresponding application packet was received.
+ *
+ * \par Implementation specific limitations
+ * Current implementation has the following limitations which will have impact to system wide
+ * behaviour:
+ * - Delayed acknowledgement scheduling not implemented:
+ * There exists a possibility that acknowledgement TX packet and application TX packet will collide
+ * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX
+ * pipeline which will trigger the retransmission algorithm within the peer protocol entity.
+ * - Delayed retransmission scheduling not implemented:
+ * There exists a possibility that retransmitted application TX packet and acknowledgement TX packet
+ * will collide in the TX pipeline having the end result that retransmitted application TX packet
+ * will be excluded from the TX pipeline.
+ * - Processing of the acknowledgement number from RX application packets:
+ * Acknowledgement number is not processed from the RX application packets having the end result
+ * that unnecessary application packet retransmissions can occur.
+ *
+ * The application TX packet processing flow is illustrated by the statemachine below.
+ *
+ * @image html hci_transport_tx_sm.svg "TX - application packet statemachine"
+ *
+ * \par Component specific configuration options
+ *
+ * The following compile time configuration options are available, and used to configure the
+ * application TX packet retransmission interval, in order to suite various application specific
+ * implementations:
+ * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits.
+ * - USED_BAUD_RATE Used uart baudrate.
+ *
+ * The following compile time configuration option is available to configure module specific
+ * behaviour:
+ * - MAX_RETRY_COUNT Max retransmission retry count for applicaton packets.
+ */
+
+#ifndef HCI_TRANSPORT_H__
+#define HCI_TRANSPORT_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Generic event callback function events. */
+typedef enum
+{
+ HCI_TRANSPORT_RX_RDY, /**< An event indicating that RX packet is ready for read. */
+ HCI_TRANSPORT_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} hci_transport_evt_type_t;
+
+/**@brief Struct containing events from the Transport layer.
+ */
+typedef struct
+{
+ hci_transport_evt_type_t evt_type; /**< Type of event. */
+} hci_transport_evt_t;
+
+/**@brief Transport layer generic event callback function type.
+ *
+ * @param[in] event Transport layer event.
+ */
+typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event);
+
+/**@brief TX done event callback function result codes. */
+typedef enum
+{
+ HCI_TRANSPORT_TX_DONE_SUCCESS, /**< Transmission success, peer transport entity has acknowledged the transmission. */
+ HCI_TRANSPORT_TX_DONE_FAILURE /**< Transmission failure. */
+} hci_transport_tx_done_result_t;
+
+/**@brief Transport layer TX done event callback function type.
+ *
+ * @param[in] result TX done event result code.
+ */
+typedef void (*hci_transport_tx_done_handler_t)(hci_transport_tx_done_result_t result);
+
+/**@brief Function for registering a generic event handler.
+ *
+ * @note Multiple registration requests will overwrite any possible existing registration.
+ *
+ * @param[in] event_handler The function to be called by the transport layer upon an event.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler);
+
+/**@brief Function for registering a handler for TX done event.
+ *
+ * @note Multiple registration requests will overwrite any possible existing registration.
+ *
+ * @param[in] event_handler The function to be called by the transport layer upon TX done
+ * event.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler);
+
+/**@brief Function for opening the transport channel and initializing the transport layer.
+ *
+ * @warning Must not be called for a channel which has been allready opened.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t hci_transport_open(void);
+
+/**@brief Function for closing the transport channel.
+ *
+ * @note Can be called multiple times and also for not opened channel.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_transport_close(void);
+
+/**@brief Function for allocating tx packet memory.
+ *
+ * @param[out] pp_memory Pointer to the packet data.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was allocated.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No memory available.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory);
+
+/**@brief Function for freeing tx packet memory.
+ *
+ * @note Memory management works in FIFO principle meaning that free order must match the alloc
+ * order.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was freed.
+ */
+uint32_t hci_transport_tx_free(void);
+
+/**@brief Function for writing a packet.
+ *
+ * @note Completion of this method does not guarantee that actual peripheral transmission would
+ * have completed.
+ *
+ * @note In case of 0 byte packet length write request, message will consist of only transport
+ * module specific headers.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue
+ * and an event will be send upon transmission completion.
+ * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not
+ * added to the transmission queue. User should wait for
+ * a appropriate event prior issuing this operation again.
+ * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Channel is not open.
+ */
+uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length);
+
+/**@brief Function for extracting received packet.
+ *
+ * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to
+ * hci_transport_rx_pkt_consume().
+ *
+ * @param[out] pp_buffer Pointer to the packet data.
+ * @param[out] p_length Length of packet data in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was extracted.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length);
+
+/**@brief Function for consuming extracted packet described by p_buffer.
+ *
+ * RX memory pointed to by p_buffer is freed and can be reused by the underlying transport layer.
+ *
+ * @param[in] p_buffer Pointer to the buffer that has been consumed.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to consume.
+ * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer.
+ */
+uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HCI_TRANSPORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c
new file mode 100644
index 0000000..8156b96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c
@@ -0,0 +1,232 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(LED_SOFTBLINK)
+#include <string.h>
+#include "led_softblink.h"
+#include "nrf_gpio.h"
+#include "app_timer.h"
+#include "nrf_assert.h"
+#include "low_power_pwm.h"
+
+/* Period for LED softblink PWM. */
+#define PWM_PERIOD UINT8_MAX
+
+/**@bref Structure to handle timer time-outs
+ *
+ */
+typedef struct
+{
+ bool leds_is_on; /**< Flag for indicating if LEDs are on. */
+ bool is_counting_up; /**< Flag for indicating if counter is incrementing or decrementing. */
+ nrfx_drv_state_t led_sb_state; /**< Indicates current state of instance. */
+ uint16_t duty_cycle; /**< Current pulse width. */
+ uint32_t bit_mask; /**< Mask of used pins. */
+ led_sb_init_params_t params; /**< Structure holding initialization parameters. */
+ low_power_pwm_config_t pwm_config; /**< Structure holding parameters for initializing low level layer. */
+ low_power_pwm_t pwm_instance; /**< Structure holding low-power PWM instance parameters. */
+}led_sb_context_t;
+
+APP_TIMER_DEF(m_led_softblink_timer);
+
+static led_sb_context_t m_led_sb = {0};
+
+/**@brief Timer event handler for softblink.
+ *
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ *
+ */
+static void led_softblink_on_timeout(void * p_context)
+{
+ static int32_t pause_ticks;
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+ ret_code_t err_code;
+
+ if (pause_ticks <= 0)
+ {
+ if (m_led_sb.is_counting_up)
+ {
+ if (m_led_sb.duty_cycle >= (m_led_sb.params.duty_cycle_max - m_led_sb.params.duty_cycle_step))
+ {
+ // Max PWM duty cycle is reached, start decrementing.
+ m_led_sb.is_counting_up = false;
+ m_led_sb.duty_cycle = m_led_sb.params.duty_cycle_max;
+ pause_ticks = m_led_sb.params.on_time_ticks ? m_led_sb.params.on_time_ticks + APP_TIMER_MIN_TIMEOUT_TICKS : 0;
+ }
+ else
+ {
+ m_led_sb.duty_cycle += m_led_sb.params.duty_cycle_step;
+ }
+ }
+ else
+ {
+ if (m_led_sb.duty_cycle <= (m_led_sb.params.duty_cycle_min + m_led_sb.params.duty_cycle_step))
+ {
+ // Min PWM duty cycle is reached, start incrementing.
+ m_led_sb.is_counting_up = true;
+ m_led_sb.duty_cycle = m_led_sb.params.duty_cycle_min;
+ pause_ticks = m_led_sb.params.off_time_ticks ? m_led_sb.params.off_time_ticks + APP_TIMER_MIN_TIMEOUT_TICKS : 0;
+ }
+ else
+ {
+ m_led_sb.duty_cycle -= m_led_sb.params.duty_cycle_step;
+ }
+ }
+ }
+ else
+ {
+ pause_ticks -= PWM_PERIOD;
+ }
+
+ err_code = low_power_pwm_duty_set(&m_led_sb.pwm_instance, m_led_sb.duty_cycle);
+
+ APP_ERROR_CHECK(err_code);
+}
+
+
+ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params)
+{
+ ret_code_t err_code;
+
+ ASSERT(m_led_sb.led_sb_state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_init_params);
+
+ if ( (p_init_params->duty_cycle_max == 0) ||
+ (p_init_params->duty_cycle_max <= p_init_params->duty_cycle_min) ||
+ (p_init_params->duty_cycle_step == 0) ||
+ (p_init_params->leds_pin_bm == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+
+
+ memset(&m_led_sb, 0, sizeof(led_sb_context_t));
+ memcpy(&m_led_sb.params, p_init_params, sizeof(led_sb_init_params_t));
+
+ m_led_sb.is_counting_up = true;
+ m_led_sb.duty_cycle = p_init_params->duty_cycle_min + p_init_params->duty_cycle_step;
+ m_led_sb.leds_is_on = false;
+ m_led_sb.bit_mask = p_init_params->leds_pin_bm;
+
+ m_led_sb.pwm_config.active_high = m_led_sb.params.active_high;
+ m_led_sb.pwm_config.bit_mask = p_init_params->leds_pin_bm;
+ m_led_sb.pwm_config.p_port = p_init_params->p_leds_port;
+ m_led_sb.pwm_config.period = PWM_PERIOD;
+ m_led_sb.pwm_config.p_timer_id = &m_led_softblink_timer;
+
+ err_code = low_power_pwm_init( &m_led_sb.pwm_instance, &m_led_sb.pwm_config, led_softblink_on_timeout);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_led_sb.led_sb_state = NRFX_DRV_STATE_INITIALIZED;
+ }
+ else
+ {
+ return err_code;
+ }
+
+ err_code = low_power_pwm_duty_set( &m_led_sb.pwm_instance, p_init_params->duty_cycle_min + p_init_params->duty_cycle_step);
+
+ return err_code;
+}
+
+
+ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask)
+{
+ ret_code_t err_code;
+
+ ASSERT(m_led_sb.led_sb_state == NRFX_DRV_STATE_INITIALIZED);
+
+ err_code = low_power_pwm_start(&m_led_sb.pwm_instance, leds_pin_bit_mask);
+
+ return err_code;
+}
+
+
+ret_code_t led_softblink_stop(void)
+{
+ ret_code_t err_code;
+
+ err_code = low_power_pwm_stop(&m_led_sb.pwm_instance);
+
+ return err_code;
+}
+
+
+void led_softblink_off_time_set(uint32_t off_time_ticks)
+{
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ m_led_sb.params.off_time_ticks = off_time_ticks;
+}
+
+
+void led_softblink_on_time_set(uint32_t on_time_ticks)
+{
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ m_led_sb.params.on_time_ticks = on_time_ticks;
+}
+
+
+ret_code_t led_softblink_uninit(void)
+{
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+
+ err_code = led_softblink_stop();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_led_sb.led_sb_state = NRFX_DRV_STATE_UNINITIALIZED;
+ }
+ else
+ {
+ return err_code;
+ }
+
+ memset(&m_led_sb, 0, sizeof(m_led_sb));
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(LED_SOFTBLINK)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h
new file mode 100644
index 0000000..936edba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup led_softblink LED softblink
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for generating a changing pulse-width modulated output signal that is used to smoothly blink LEDs.
+ *
+ * @details This module provides an LED softblink implementation using timers and GPIO.
+ *
+ * LED softblink needs one timer. It can use any number of output channels that are available.
+ *
+ * Only one instance of LED softblink can run at a time.
+ */
+
+#ifndef LED_SOFTBLINK_H__
+#define LED_SOFTBLINK_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Structure holding the initialization parameters.
+ */
+typedef struct
+{
+ bool active_high; /**< Activate negative polarity. */
+ uint8_t duty_cycle_max; /**< Maximum impulse width. */
+ uint8_t duty_cycle_min; /**< Minimum impulse width. */
+ uint8_t duty_cycle_step; /**< Cycle step. */
+ uint32_t off_time_ticks; /**< Ticks to stay in low impulse state. */
+ uint32_t on_time_ticks; /**< Ticks to stay in high impulse state. */
+ uint32_t leds_pin_bm; /**< Mask of used LEDs. */
+ NRF_GPIO_Type * p_leds_port; /**< Port of used LEDs mask. */
+}led_sb_init_params_t;
+
+/**
+ * @name Default settings
+ * @brief Default settings for LED softblink.
+ * @{
+ */
+#define LED_SB_INIT_PARAMS_ACTIVE_HIGH false
+#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX 220
+#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN 0
+#define LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP 5
+#define LED_SB_INIT_PARAMS_OFF_TIME_TICKS 65536
+#define LED_SB_INIT_PARAMS_ON_TIME_TICKS 0
+#define LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask) (mask)
+#define LED_SB_INIT_PARAMS_LEDS_PORT NRF_GPIO
+/** @} */
+
+/**
+ * @brief LED softblink default configuration.
+ */
+#define LED_SB_INIT_DEFAULT_PARAMS(mask) \
+{ \
+ .active_high = LED_SB_INIT_PARAMS_ACTIVE_HIGH, \
+ .duty_cycle_max = LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX, \
+ .duty_cycle_min = LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN, \
+ .duty_cycle_step = LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP, \
+ .off_time_ticks = LED_SB_INIT_PARAMS_OFF_TIME_TICKS, \
+ .on_time_ticks = LED_SB_INIT_PARAMS_ON_TIME_TICKS, \
+ .leds_pin_bm = LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask), \
+ .p_leds_port = LED_SB_INIT_PARAMS_LEDS_PORT \
+}
+
+/**
+ * @brief Function for initializing LED softblink.
+ *
+ * @param[in] p_init_params Pointer to the initialization structure.
+ *
+ * @return Values returned by @ref app_timer_create.
+ */
+ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params);
+
+/**
+ * @brief Function for starting to blink LEDs.
+ *
+ * @param[in] leds_pin_bit_mask Bit mask containing the pins for the LEDs to be blinked.
+ *
+ * @return Values returned by @ref app_timer_start.
+ */
+ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask);
+
+/**
+ * @brief Function for stopping to blink LEDs.
+ *
+ * @return Values returned by @ref app_timer_stop.
+ */
+ret_code_t led_softblink_stop(void);
+
+/**
+ * @brief Function for setting the off time.
+ *
+ * This function configures the time that the LEDs will be off between each blink.
+ *
+ * @param[in] off_time_ticks Off time in ticks.
+ *
+ */
+void led_softblink_off_time_set(uint32_t off_time_ticks);
+
+/**
+ * @brief Function for setting the on time.
+ *
+ * This function configures the time that the LEDs will be on between each blink.
+ *
+ * @param[in] on_time_ticks On time in ticks.
+ *
+ */
+void led_softblink_on_time_set(uint32_t on_time_ticks);
+
+/**
+ * @brief Function for uninitializing LED softblink.
+ *
+ * @retval NRF_SUCCESS If LED softblink was uninitialized successfully.
+ */
+ret_code_t led_softblink_uninit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LED_SOFTBLINK_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c
new file mode 100644
index 0000000..1331a25
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c
@@ -0,0 +1,258 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(LOW_POWER_PWM)
+#include <string.h>
+#include "low_power_pwm.h"
+#include "nrf_gpio.h"
+#include "app_timer.h"
+#include "nrf_assert.h"
+
+/**
+ * @brief Function for turning on pins.
+ *
+ * Sets the pin high state according to active_high parameter.
+ *
+ * @param[in] p_pwm_instance Pointer to instance of low-power PWM.
+ */
+__STATIC_INLINE void pin_on(low_power_pwm_t * p_pwm_instance)
+{
+ if (p_pwm_instance->active_high)
+ {
+ nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ else
+ {
+ nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ p_pwm_instance->pin_is_on = true;
+}
+
+
+/**
+ * @brief Function for turning off pins.
+ *
+ * Sets the pin low state according to active_high parameter.
+ *
+ * @param[in] p_pwm_instance Pointer to instance of low-power PWM.
+ */
+__STATIC_INLINE void pin_off(low_power_pwm_t * p_pwm_instance)
+{
+ if (p_pwm_instance->active_high)
+ {
+ nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ else
+ {
+ nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ p_pwm_instance->pin_is_on = false;
+}
+
+
+/**
+ * @brief Timer event handler for PWM.
+ *
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ *
+ */
+static void pwm_timeout_handler(void * p_context)
+{
+ ret_code_t err_code;
+ uint8_t duty_cycle;
+
+ low_power_pwm_t * p_pwm_instance = (low_power_pwm_t *)p_context;
+
+ if (p_pwm_instance->evt_type == LOW_POWER_PWM_EVENT_PERIOD)
+ {
+ if (p_pwm_instance->handler)
+ {
+ p_pwm_instance->handler(p_pwm_instance);
+
+ if (p_pwm_instance->pwm_state != NRFX_DRV_STATE_POWERED_ON)
+ {
+ return;
+ }
+ }
+
+ duty_cycle = p_pwm_instance->duty_cycle;
+
+ if (duty_cycle == p_pwm_instance->period) // Process duty cycle 100%
+ {
+ pin_on(p_pwm_instance);
+ p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS;
+ }
+ else if (duty_cycle == 0) // Process duty cycle 0%
+ {
+ pin_off(p_pwm_instance);
+ p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS;
+ }
+ else // Process any other duty cycle than 0 or 100%
+ {
+ pin_on(p_pwm_instance);
+ p_pwm_instance->timeout_ticks = ((duty_cycle * p_pwm_instance->period)>>8) +
+ APP_TIMER_MIN_TIMEOUT_TICKS;
+ // setting next state
+ p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_DUTY_CYCLE;
+ }
+ }
+ else
+ {
+ pin_off(p_pwm_instance);
+ p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD;
+ p_pwm_instance->timeout_ticks = (((p_pwm_instance->period - p_pwm_instance->duty_cycle) *
+ p_pwm_instance->period)>>8) + APP_TIMER_MIN_TIMEOUT_TICKS;
+ }
+
+ if (p_pwm_instance->pwm_state == NRFX_DRV_STATE_POWERED_ON)
+ {
+ err_code = app_timer_start(*p_pwm_instance->p_timer_id, p_pwm_instance->timeout_ticks, p_pwm_instance);
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance,
+ low_power_pwm_config_t const * p_pwm_config,
+ app_timer_timeout_handler_t handler)
+{
+ ASSERT(p_pwm_instance->pwm_state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_pwm_config->bit_mask != 0);
+ ASSERT(p_pwm_config->p_port != NULL);
+ ASSERT(p_pwm_config->period != 0);
+
+ ret_code_t err_code;
+ uint32_t bit_mask;
+ uint32_t pin_number = 0;
+
+ p_pwm_instance->handler = handler;
+
+ bit_mask = p_pwm_config->bit_mask;
+
+ p_pwm_instance->active_high = p_pwm_config->active_high;
+ p_pwm_instance->bit_mask = p_pwm_config->bit_mask;
+ p_pwm_instance->bit_mask_toggle = p_pwm_config->bit_mask;
+ p_pwm_instance->p_port = p_pwm_config->p_port;
+ p_pwm_instance->period = p_pwm_config->period;
+ p_pwm_instance->p_timer_id = p_pwm_config->p_timer_id;
+
+ err_code = app_timer_create(p_pwm_instance->p_timer_id, APP_TIMER_MODE_SINGLE_SHOT, pwm_timeout_handler);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ while (bit_mask)
+ {
+ if (bit_mask & 0x1UL)
+ {
+ nrf_gpio_cfg_output(pin_number);
+ }
+
+ pin_number++;
+ bit_mask >>= 1UL;
+ }
+
+ pin_off(p_pwm_instance);
+ p_pwm_instance->pwm_state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance,
+ uint32_t pin_bit_mask)
+{
+ ASSERT(p_pwm_instance->pwm_state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(((p_pwm_instance->bit_mask) & pin_bit_mask) != 0x00);
+
+ p_pwm_instance->pwm_state = NRFX_DRV_STATE_POWERED_ON;
+ p_pwm_instance->bit_mask_toggle = pin_bit_mask;
+
+ pin_off(p_pwm_instance);
+
+ p_pwm_instance->bit_mask |= pin_bit_mask;
+ p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD;
+
+ app_timer_timeout_handler_t handler = p_pwm_instance->handler;
+ p_pwm_instance->handler = NULL;
+ pwm_timeout_handler(p_pwm_instance);
+ p_pwm_instance->handler = handler;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance)
+{
+ ASSERT(p_pwm_instance->pwm_state == NRFX_DRV_STATE_POWERED_ON);
+
+ ret_code_t err_code;
+
+ err_code = app_timer_stop(*p_pwm_instance->p_timer_id);
+
+ pin_off(p_pwm_instance);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_pwm_instance->pwm_state = NRFX_DRV_STATE_INITIALIZED;
+
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle)
+{
+ if ( p_pwm_instance->period < duty_cycle)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_pwm_instance->duty_cycle = duty_cycle;
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(LOW_POWER_PWM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h
new file mode 100644
index 0000000..8a9421e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup low_power_pwm Low-power PWM
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for generating a low-power pulse-width modulated output signal.
+ *
+ * This module provides a low-power PWM implementation using app_timers and GPIO.
+ *
+ * Each low-power PWM instance utilizes one app_timer. This means it runs on RTC
+ * and does not require HFCLK to be running. There can be any number of output
+ * channels per instance.
+ */
+
+#ifndef LOW_POWER_PWM_H__
+#define LOW_POWER_PWM_H__
+
+#include <nrfx.h>
+#include "app_timer.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Event types.
+ */
+typedef enum
+{
+ LOW_POWER_PWM_EVENT_PERIOD = 0,
+ LOW_POWER_PWM_EVENT_DUTY_CYCLE
+}low_power_pwm_evt_type_t;
+
+/**@brief Application time-out handler type. */
+typedef void (*low_power_pwm_timeout_user)(void * p_context, low_power_pwm_evt_type_t evt_type);
+
+/**
+ * @brief Structure holding the initialization parameters.
+ */
+typedef struct
+{
+ bool active_high; /**< Activate negative polarity. */
+ uint8_t period; /**< Width of the low_power_pwm period. */
+ NRF_GPIO_Type * p_port; /**< Port used to work on selected mask. */
+ uint32_t bit_mask; /**< Pins to be initialized. */
+ app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */
+} low_power_pwm_config_t;
+
+
+/**
+ * @name Default settings
+ * @{
+ *
+ * @brief Default parameters for the @ref low_power_pwm_config_t structure.
+ *
+ */
+#define LOW_POWER_PWM_CONFIG_ACTIVE_HIGH false
+#define LOW_POWER_PWM_CONFIG_PERIOD UINT8_MAX
+#define LOW_POWER_PWM_CONFIG_PORT NRF_GPIO
+#define LOW_POWER_PWM_CONFIG_BIT_MASK(mask) (mask)
+/** @} */
+
+/**
+ * @brief Low-power PWM default configuration.
+ */
+#define LOW_POWER_PWM_DEFAULT_CONFIG(mask) \
+{ \
+ .active_high = LOW_POWER_PWM_CONFIG_ACTIVE_HIGH , \
+ .period = LOW_POWER_PWM_CONFIG_PERIOD , \
+ .p_port = LOW_POWER_PWM_CONFIG_PORT, \
+ .bit_mask = LOW_POWER_PWM_CONFIG_BIT_MASK(mask) \
+}
+/**
+ * @cond (NODOX)
+ * @defgroup low_power_pwm_internal Auxiliary internal types declarations
+ * @brief Module for internal usage inside the library only.
+ * @details These definitions are available to the user, but they should not
+ * be accessed directly. Use @ref low_power_pwm_duty_set instead.
+ * @{
+ *
+ */
+
+ /**
+ * @brief Structure holding parameters of a given low-power PWM instance.
+ */
+ struct low_power_pwm_s
+ {
+ bool active_high; /**< Activate negative polarity. */
+ bool pin_is_on; /**< Indicates the current state of the pin. */
+ uint8_t period; /**< Width of the low_power_pwm period. */
+ uint8_t duty_cycle; /**< Width of high pulse. */
+ nrfx_drv_state_t pwm_state; /**< Indicates the current state of the PWM instance. */
+ uint32_t bit_mask; /**< Pins to be initialized. */
+ uint32_t bit_mask_toggle; /**< Pins to be toggled. */
+ uint32_t timeout_ticks; /**< Value to start the next app_timer. */
+ low_power_pwm_evt_type_t evt_type; /**< Slope that triggered time-out. */
+ app_timer_timeout_handler_t handler; /**< User handler to be called in the time-out handler. */
+ app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */
+ NRF_GPIO_Type * p_port; /**< Port used with pin bit mask. */
+ };
+
+/** @}
+ * @endcond
+ */
+
+/**
+ * @brief Internal structure holding parameters of a low-power PWM instance.
+ */
+typedef struct low_power_pwm_s low_power_pwm_t;
+
+
+/**
+ * @brief Function for initializing a low-power PWM instance.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be started.
+ * @param[in] p_pwm_config Pointer to the configuration structure.
+ * @param[in] handler User function to be called in case of time-out.
+ *
+ * @return Values returned by @ref app_timer_create.
+ */
+ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance,
+ low_power_pwm_config_t const * p_pwm_config,
+ app_timer_timeout_handler_t handler);
+
+
+/**
+ * @brief Function for starting a low-power PWM instance.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be started.
+ * @param[in] pins_bit_mask Bit mask of pins to be started.
+ *
+ * @return Values returned by @ref app_timer_start.
+ */
+ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance,
+ uint32_t pins_bit_mask);
+
+
+/**
+ * @brief Function for stopping a low-power PWM instance.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be stopped.
+ *
+ * @return Values returned by @ref app_timer_stop.
+ */
+ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance);
+
+
+/**
+ * @brief Function for setting a new high pulse width for a given instance.
+ *
+ * This function can be called from the timer handler.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be changed.
+ * @param[in] duty_cycle New high pulse width. 0 means that the pin is always off. 255 means that it is always on.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the function returned an error because of invalid parameters.
+ */
+ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LOW_POWER_PWM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c
new file mode 100644
index 0000000..a64b198
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c
@@ -0,0 +1,931 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(MEM_MANAGER)
+#include "mem_manager.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME mem_mngr
+
+#if MEM_MANAGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL MEM_MANAGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MEM_MANAGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MEM_MANAGER_CONFIG_DEBUG_COLOR
+#else //MEM_MANAGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //MEM_MANAGER_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**
+ * @defgroup memory_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 MM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_mm_mutex) /**< Lock module using mutex. */
+#define MM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mm_mutex) /**< Unlock module using mutex. */
+/** @} */
+
+#undef NULL_PARAM_CHECK
+#undef NULL_PARAM_CHECK_VOID
+#undef VERIFY_MODULE_INITIALIZED
+#undef VERIFY_MODULE_INITIALIZED_VOID
+#undef VERIFY_REQUESTED_SIZE
+#undef VERIFY_REQUESTED_SIZE_VOID
+
+#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+
+/**
+ * @brief Macro for verifying NULL parameters.
+ * Returning with an appropriate error code on failure.
+ *
+ * @param[in] PARAM Parameter checked for NULL.
+ *
+ * @retval (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) when @ref PARAM is NULL.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \
+ }
+
+/**
+ * @brief Macro for verifying NULL parameters are not passed to API and returning on failure.
+ *
+ * @param[in] PARAM Parameter checked for NULL.
+ */
+#define NULL_PARAM_CHECK_VOID(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return; \
+ }
+
+
+/**
+ * @brief Macro for verifying module's initialization status.
+ * Returning with an appropriate error code on failure.
+ *
+ * @retval (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) module is uninitialized.
+ */
+#define VERIFY_MODULE_INITIALIZED() \
+ do \
+ { \
+ if (!m_module_initialized) \
+ { \
+ return (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \
+ } \
+ } while (0)
+
+/**
+ * @brief Macro for verifying module's initialization status and returning on failure.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID() \
+ do \
+ { \
+ if (!m_module_initialized) \
+ { \
+ return; \
+ } \
+ } while (0)
+
+
+/**
+ * @brief Macro for verifying requested size of memory does not exceed maximum block
+ * size supported by the module. Returning with appropriate error code on failure.
+ *
+ * @param[in] SIZE Requested size to be allocated.
+ *
+ * @retval (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) if requested size is greater
+ * than the largest block size managed by the module.
+ */
+#define VERIFY_REQUESTED_SIZE(SIZE) \
+ do \
+ { \
+ if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \
+ } \
+ } while (0)
+
+
+/**
+ * @brief Macro for verifying requested size of memory does not exceed maximum block
+ * size supported by the module. Returns on failure.
+ *
+ * @param[in] SIZE Requested size to be allocated.
+ */
+#define VERIFY_REQUESTED_SIZE_VOID(SIZE) \
+ do \
+ { \
+ if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \
+ { \
+ return; \
+ } \
+ } while (0)
+
+
+/**@} */
+#else //MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_MODULE_INITIALIZED()
+#define VERIFY_REQUESTED_SIZE(SIZE)
+
+#endif //MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+
+/**@brief Setting defaults in case XXSmall block not used by application. */
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
+ #define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 0
+ #define XXSMALL_BLOCK_START 0
+ #define XXSMALL_BLOCK_END 0
+ #define XXSMALL_MEMORY_START 0
+#endif // MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+
+
+/**@brief Setting defaults in case XSmall block not used by application. */
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT
+ #define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 0
+ #define XSMALL_BLOCK_START 0
+ #define XSMALL_BLOCK_END 0
+ #define XSMALL_MEMORY_START 0
+#endif // MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+
+
+/**@brief Setting defaults in case Small block not used by application. */
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT
+ #define MEMORY_MANAGER_SMALL_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_SMALL_BLOCK_SIZE 0
+ #define SMALL_BLOCK_START 0
+ #define SMALL_BLOCK_END 0
+ #define SMALL_MEMORY_START 0
+#endif // MEMORY_MANAGER_SMALL_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case Medium block not used by application. */
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+ #define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 0
+ #define MEDIUM_BLOCK_START 0
+ #define MEDIUM_BLOCK_END 0
+ #define MEDIUM_MEMORY_START 0
+#endif // MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case Large block not used by application. */
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT
+ #define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_LARGE_BLOCK_SIZE 0
+ #define LARGE_BLOCK_START 0
+ #define LARGE_BLOCK_END 0
+ #define LARGE_MEMORY_START 0
+#endif // MEMORY_MANAGER_LARGE_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case XLarge block not used by application. */
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+ #define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 0
+ #define XLARGE_BLOCK_START 0
+ #define XLARGE_BLOCK_END 0
+ #define XLARGE_MEMORY_START 0
+#endif // MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case XXLarge block not used by application. */
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+ #define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 0
+ #define XXLARGE_BLOCK_START 0
+ #define XXLARGE_BLOCK_END 0
+ #define XXLARGE_MEMORY_START 0
+#endif // MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+
+
+/**@brief Based on which blocks are defined, MAX_MEM_SIZE is determined.
+ *
+ * @note Also, in case none of these are defined, a compile time error is indicated.
+ */
+#if (MEMORY_MANAGER_XXLARGE_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+#elif (MEMORY_MANAGER_XLARGE_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XLARGE_BLOCK_SIZE
+#elif (MEMORY_MANAGER_LARGE_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_LARGE_BLOCK_SIZE
+#elif (MEMORY_MANAGER_MEDIUM_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
+#elif (MEMORY_MANAGER_SMALL_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_SMALL_BLOCK_SIZE
+#elif (MEMORY_MANAGER_XSMALL_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+#elif (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+#else
+ #err "One of MEMORY_MANAGER_SMALL_BLOCK_COUNT, MEMORY_MANAGER_MEDIUM_BLOCK_COUNT or \
+ or MEMORY_MANAGER_LARGE_BLOCK_COUNT should be defined."
+#endif
+
+/**@brief XXSmall block start index in case XXSmall Block is defined. */
+#ifndef XXSMALL_BLOCK_START
+#define XXSMALL_BLOCK_START 0
+#endif // XXSMALL_BLOCK_START
+
+
+/**@brief XSmall block start index in case XSmall Block is defined. */
+#ifndef XSMALL_BLOCK_START
+#define XSMALL_BLOCK_START (XXSMALL_BLOCK_START + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT)
+#endif // XSMALL_BLOCK_START
+
+
+/**@brief Small block start index in case Small Block is defined. */
+#ifndef SMALL_BLOCK_START
+#define SMALL_BLOCK_START (XSMALL_BLOCK_START + MEMORY_MANAGER_XSMALL_BLOCK_COUNT)
+#endif // SMALL_BLOCK_START
+
+
+/**@brief Medium block start index in case Medium Block is defined. */
+#ifndef MEDIUM_BLOCK_START
+#define MEDIUM_BLOCK_START (SMALL_BLOCK_START + MEMORY_MANAGER_SMALL_BLOCK_COUNT)
+#endif // MEDIUM_BLOCK_START
+
+
+/**@brief Large block start index in case Large Block is defined. */
+#ifndef LARGE_BLOCK_START
+#define LARGE_BLOCK_START (MEDIUM_BLOCK_START + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT)
+#endif // LARGE_BLOCK_START
+
+
+/**@brief XLarge block start index in case XLarge Block is defined. */
+#ifndef XLARGE_BLOCK_START
+#define XLARGE_BLOCK_START (LARGE_BLOCK_START + MEMORY_MANAGER_LARGE_BLOCK_COUNT)
+#endif // XLARGE_BLOCK_START
+
+/**@brief XXLarge block start index in case XXLarge Block is defined. */
+#ifndef XXLARGE_BLOCK_START
+#define XXLARGE_BLOCK_START (XLARGE_BLOCK_START + MEMORY_MANAGER_XLARGE_BLOCK_COUNT)
+#endif //XXLARGE_BLOCK_START
+
+
+/**@brief XXSmall block end index in case XXSmall Block is defined. */
+#ifndef XXSMALL_BLOCK_END
+#define XXSMALL_BLOCK_END (XXSMALL_BLOCK_START + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT)
+#endif // XXSMALL_BLOCK_END
+
+/**@brief XSmall block end index in case XSmall Block is defined. */
+#ifndef XSMALL_BLOCK_END
+#define XSMALL_BLOCK_END (XSMALL_BLOCK_START + MEMORY_MANAGER_XSMALL_BLOCK_COUNT)
+#endif // XSMALL_BLOCK_END
+
+
+/**@brief Small block end index in case Small Block is defined. */
+#ifndef SMALL_BLOCK_END
+#define SMALL_BLOCK_END (SMALL_BLOCK_START + MEMORY_MANAGER_SMALL_BLOCK_COUNT)
+#endif // SMALL_BLOCK_END
+
+
+/**@brief Medium block end index in case Medium Block is defined. */
+#ifndef MEDIUM_BLOCK_END
+#define MEDIUM_BLOCK_END (MEDIUM_BLOCK_START + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT)
+#endif // MEDIUM_BLOCK_END
+
+
+/**@brief Large block end index in case Large Block is defined. */
+#ifndef LARGE_BLOCK_END
+#define LARGE_BLOCK_END (LARGE_BLOCK_START + MEMORY_MANAGER_LARGE_BLOCK_COUNT)
+#endif // LARGE_BLOCK_END
+
+
+/**@brief XLarge block end index in case XLarge Block is defined. */
+#ifndef XLARGE_BLOCK_END
+#define XLARGE_BLOCK_END (XLARGE_BLOCK_START + MEMORY_MANAGER_XLARGE_BLOCK_COUNT)
+#endif // XLARGE_BLOCK_END
+
+
+/**@brief XXLarge block end index in case XXLarge Block is defined. */
+#ifndef XXLARGE_BLOCK_END
+#define XXLARGE_BLOCK_END (XXLARGE_BLOCK_START + MEMORY_MANAGER_XXLARGE_BLOCK_COUNT)
+#endif //XXLARGE_BLOCK_END
+
+
+#define XXSMALL_MEMORY_SIZE (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT * MEMORY_MANAGER_XXSMALL_BLOCK_SIZE)
+#define XSMALL_MEMORY_SIZE (MEMORY_MANAGER_XSMALL_BLOCK_COUNT * MEMORY_MANAGER_XSMALL_BLOCK_SIZE)
+#define SMALL_MEMORY_SIZE (MEMORY_MANAGER_SMALL_BLOCK_COUNT * MEMORY_MANAGER_SMALL_BLOCK_SIZE)
+#define MEDIUM_MEMORY_SIZE (MEMORY_MANAGER_MEDIUM_BLOCK_COUNT * MEMORY_MANAGER_MEDIUM_BLOCK_SIZE)
+#define LARGE_MEMORY_SIZE (MEMORY_MANAGER_LARGE_BLOCK_COUNT * MEMORY_MANAGER_LARGE_BLOCK_SIZE)
+#define XLARGE_MEMORY_SIZE (MEMORY_MANAGER_XLARGE_BLOCK_COUNT * MEMORY_MANAGER_XLARGE_BLOCK_SIZE)
+#define XXLARGE_MEMORY_SIZE (MEMORY_MANAGER_XXLARGE_BLOCK_COUNT * MEMORY_MANAGER_XXLARGE_BLOCK_SIZE)
+
+
+/**@brief XXSmall memory start index in case XXSmall Block is defined. */
+#ifndef XXSMALL_MEMORY_START
+#define XXSMALL_MEMORY_START 0
+#endif // XXSMALL_MEMORY_START
+
+
+/**@brief XSmall memory start index in case XSmall Block is defined. */
+#ifndef XSMALL_MEMORY_START
+#define XSMALL_MEMORY_START (XXSMALL_MEMORY_START + XXSMALL_MEMORY_SIZE)
+#endif // XSMALL_MEMORY_START
+
+
+/**@brief Small memory start index in case Small Block is defined. */
+#ifndef SMALL_MEMORY_START
+#define SMALL_MEMORY_START (XSMALL_MEMORY_START + XSMALL_MEMORY_SIZE)
+#endif // SMALL_MEMORY_START
+
+
+/**@brief Medium memory start index in case Medium Block is defined. */
+#ifndef MEDIUM_MEMORY_START
+#define MEDIUM_MEMORY_START (SMALL_MEMORY_START + SMALL_MEMORY_SIZE)
+#endif // MEDIUM_MEMORY_START
+
+
+/**@brief Large memory start index in case Large Block is defined. */
+#ifndef LARGE_MEMORY_START
+#define LARGE_MEMORY_START (MEDIUM_MEMORY_START + MEDIUM_MEMORY_SIZE)
+#endif // LARGE_MEMORY_START
+
+
+/**@brief XLarge memory start index in case XLarge Block is defined. */
+#ifndef XLARGE_MEMORY_START
+#define XLARGE_MEMORY_START (LARGE_MEMORY_START + LARGE_MEMORY_SIZE)
+#endif // XLARGE_MEMORY_START
+
+
+/**@brief XXLarge memory start index in case XXLarge Block is defined. */
+#ifndef XXLARGE_MEMORY_START
+#define XXLARGE_MEMORY_START (XLARGE_MEMORY_START + XLARGE_MEMORY_SIZE)
+#endif // XLARGE_MEMORY_START
+
+
+/**@brief Total count of block managed by the module. */
+#define TOTAL_BLOCK_COUNT (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT + \
+ MEMORY_MANAGER_XSMALL_BLOCK_COUNT + \
+ MEMORY_MANAGER_SMALL_BLOCK_COUNT + \
+ MEMORY_MANAGER_MEDIUM_BLOCK_COUNT + \
+ MEMORY_MANAGER_LARGE_BLOCK_COUNT + \
+ MEMORY_MANAGER_XLARGE_BLOCK_COUNT + \
+ MEMORY_MANAGER_XXLARGE_BLOCK_COUNT)
+
+
+/**@brief Total memory managed by the module. */
+#define TOTAL_MEMORY_SIZE (XXSMALL_MEMORY_SIZE + \
+ XSMALL_MEMORY_SIZE + \
+ SMALL_MEMORY_SIZE + \
+ MEDIUM_MEMORY_SIZE + \
+ LARGE_MEMORY_SIZE + \
+ XLARGE_MEMORY_SIZE + \
+ XXLARGE_MEMORY_SIZE)
+
+
+#define BLOCK_CAT_COUNT 7 /**< Block category count is 7 (xxsmall, xsmall, small, medium, large, xlarge, xxlarge). Having one of the block count to zero has no impact on this count. */
+#define BLOCK_CAT_XXS 0 /**< Extra Extra Small category identifier. */
+#define BLOCK_CAT_XS 1 /**< Extra Small category identifier. */
+#define BLOCK_CAT_SMALL 2 /**< Small category identifier. */
+#define BLOCK_CAT_MEDIUM 3 /**< Medium category identifier. */
+#define BLOCK_CAT_LARGE 4 /**< Large category identifier. */
+#define BLOCK_CAT_XL 5 /**< Extra Large category identifier. */
+#define BLOCK_CAT_XXL 6 /**< Extra Extra Large category identifier. */
+
+#define BITMAP_SIZE 32 /**< Bitmap size for each word used to contain block information. */
+#define BLOCK_BITMAP_ARRAY_SIZE CEIL_DIV(TOTAL_BLOCK_COUNT, BITMAP_SIZE) /**< Determines number of blocks needed for book keeping availability status of all blocks. */
+
+
+/**@brief Lookup table for maximum memory size per block category. */
+static const uint32_t m_block_size[BLOCK_CAT_COUNT] =
+{
+ MEMORY_MANAGER_XXSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_XSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_SMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_MEDIUM_BLOCK_SIZE,
+ MEMORY_MANAGER_LARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XLARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+};
+
+/**@brief Lookup table for block start index for each block category. */
+static const uint32_t m_block_start[BLOCK_CAT_COUNT] =
+{
+ XXSMALL_BLOCK_START,
+ XSMALL_BLOCK_START,
+ SMALL_BLOCK_START,
+ MEDIUM_BLOCK_START,
+ LARGE_BLOCK_START,
+ XLARGE_BLOCK_START,
+ XXLARGE_BLOCK_START
+};
+
+/**@brief Lookup table for last block index for each block category. */
+static const uint32_t m_block_end[BLOCK_CAT_COUNT] =
+{
+ XXSMALL_BLOCK_END,
+ XSMALL_BLOCK_END,
+ SMALL_BLOCK_END,
+ MEDIUM_BLOCK_END,
+ LARGE_BLOCK_END,
+ XLARGE_BLOCK_END,
+ XXLARGE_BLOCK_END
+};
+
+/**@brief Lookup table for memory start range for each block category. */
+static const uint32_t m_block_mem_start[BLOCK_CAT_COUNT] =
+{
+ XXSMALL_MEMORY_START,
+ XSMALL_MEMORY_START,
+ SMALL_MEMORY_START,
+ MEDIUM_MEMORY_START,
+ LARGE_MEMORY_START,
+ XLARGE_MEMORY_START,
+ XXLARGE_MEMORY_START
+};
+
+static uint8_t m_memory[TOTAL_MEMORY_SIZE]; /**< Memory managed by the module. */
+static uint32_t m_mem_pool[BLOCK_BITMAP_ARRAY_SIZE]; /**< Bitmap used for book-keeping availability of all blocks managed by the module. */
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+/**@brief Lookup table for descriptive strings for each block category. */
+static const char * m_block_desc_str[BLOCK_CAT_COUNT] =
+{
+ "XXSmall",
+ "XSmall",
+ "Small",
+ "Medium",
+ "Large",
+ "XLarge",
+ "XXLarge"
+};
+
+/**@brief Table for book keeping smallest size allocated in each block range. */
+static uint32_t m_min_size[BLOCK_CAT_COUNT] =
+{
+ MEMORY_MANAGER_XXSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_XSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_SMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_MEDIUM_BLOCK_SIZE,
+ MEMORY_MANAGER_LARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XLARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+};
+
+/**@brief Table for book keeping largest size allocated in each block range. */
+static uint32_t m_max_size[BLOCK_CAT_COUNT];
+
+/**@brief Global pointing to minimum size holder for block type being allocated. */
+static uint32_t * p_min_size;
+
+/**@brief Global pointing to maximum size holder for block type being allocated. */
+static uint32_t * p_max_size;
+
+/**@brief Lookup table for count of block available in each block category. */
+static uint32_t m_block_count[BLOCK_CAT_COUNT] =
+{
+ MEMORY_MANAGER_XXSMALL_BLOCK_COUNT,
+ MEMORY_MANAGER_XSMALL_BLOCK_COUNT,
+ MEMORY_MANAGER_SMALL_BLOCK_COUNT,
+ MEMORY_MANAGER_MEDIUM_BLOCK_COUNT,
+ MEMORY_MANAGER_LARGE_BLOCK_COUNT,
+ MEMORY_MANAGER_XLARGE_BLOCK_COUNT,
+ MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+};
+
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+SDK_MUTEX_DEFINE(m_mm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */
+#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+
+/**@brief Function to get X and Y coordinates.
+ *
+ * @details Function to get X and Y co-ordinates for the block identified by index.
+ * Here, X determines relevant word for the block. Y determines the actual bit in the word.
+ *
+ * @param[in] index Identifies the block.
+ * @param[out] p_x Points to the word that contains the bit representing the block.
+ * @param[out] p_y Contains the bitnumber in the the word 'X' relevant to the block.
+ */
+static __INLINE void get_block_coordinates(uint32_t block_index, uint32_t * p_x, uint32_t * p_y)
+{
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ const uint32_t x = block_index / BITMAP_SIZE;
+ const uint32_t y = (block_index - x * BITMAP_SIZE);
+
+ (*p_x) = x;
+ (*p_y) = y;
+}
+
+
+/**@brief Initializes the block by setting it to be free. */
+static void block_init (uint32_t block_index)
+{
+ uint32_t x;
+ uint32_t y;
+
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ get_block_coordinates(block_index, &x, &y);
+
+ // Set bit related to the block to indicate that the block is free.
+ SET_BIT(m_mem_pool[x], y);
+}
+
+
+/**@brief Function to get the category of the block of size 'size' or block number 'block_index'.*/
+static __INLINE uint32_t get_block_cat(uint32_t size, uint32_t block_index)
+{
+ for (uint32_t block_cat = 0; block_cat < BLOCK_CAT_COUNT; block_cat++)
+ {
+ if (((size != 0) && (size <= m_block_size[block_cat]) &&
+ (m_block_end[block_cat] != m_block_start[block_cat])) ||
+ (block_index < m_block_end[block_cat]))
+ {
+ return block_cat;
+ }
+ }
+
+ return 0;
+}
+
+
+/**@brief Function to get the size of the block number 'block_index'. */
+static __INLINE uint32_t get_block_size(uint32_t block_index)
+{
+ const uint32_t block_cat = get_block_cat(0, block_index);
+
+ #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ p_min_size = &m_min_size[block_cat];
+ p_max_size = &m_max_size[block_cat];
+ #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+ return m_block_size[block_cat];
+}
+
+
+/**@brief Function to free the block identified by block number 'block_index'. */
+static bool is_block_free(uint32_t block_index)
+{
+ uint32_t x;
+ uint32_t y;
+
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ get_block_coordinates(block_index, &x, &y);
+
+ return IS_SET(m_mem_pool[x], y);
+}
+
+
+/**@brief Function to allocate the block identified by block number 'block_index'. */
+static void block_allocate(uint32_t block_index)
+{
+ uint32_t x;
+ uint32_t y;
+
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ get_block_coordinates(block_index, &x, &y);
+
+ CLR_BIT(m_mem_pool[x], y);
+}
+
+
+uint32_t nrf_mem_init(void)
+{
+ NRF_LOG_DEBUG(">> %s.", (uint32_t)__func__);
+
+ SDK_MUTEX_INIT(m_mm_mutex);
+
+ MM_MUTEX_LOCK();
+
+ uint32_t block_index = 0;
+
+ for (block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++)
+ {
+ block_init(block_index);
+ }
+
+#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+ m_module_initialized = true;
+#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ nrf_mem_diagnose();
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+ MM_MUTEX_UNLOCK();
+
+ NRF_LOG_DEBUG("<< %s.", (uint32_t)__func__);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size)
+{
+ VERIFY_MODULE_INITIALIZED();
+ NULL_PARAM_CHECK(pp_buffer);
+ NULL_PARAM_CHECK(p_size);
+
+ const uint32_t requested_size = (*p_size);
+
+ VERIFY_REQUESTED_SIZE(requested_size);
+
+ NRF_LOG_DEBUG(">> %s, size 0x%04lX.", (uint32_t)__func__, requested_size);
+
+ MM_MUTEX_LOCK();
+
+ const uint32_t block_cat = get_block_cat(requested_size, TOTAL_BLOCK_COUNT);
+ uint32_t block_index = m_block_start[block_cat];
+ uint32_t memory_index = m_block_mem_start[block_cat];
+ uint32_t err_code = (NRF_ERROR_NO_MEM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE);
+
+ NRF_LOG_DEBUG("Start index for the pool = 0x%08lX, total block count 0x%08X",
+ block_index,
+ TOTAL_BLOCK_COUNT);
+
+ for (; block_index < TOTAL_BLOCK_COUNT; block_index++)
+ {
+ uint32_t block_size = get_block_size(block_index);
+
+ if (is_block_free(block_index) == true)
+ {
+ NRF_LOG_DEBUG("Reserving block 0x%08lX", block_index);
+
+ // Search succeeded, found free block.
+ err_code = NRF_SUCCESS;
+
+ // Allocate block.
+ block_allocate(block_index);
+
+ (*pp_buffer) = &m_memory[memory_index];
+ (*p_size) = block_size;
+
+ #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ (*p_min_size) = MIN((*p_min_size), requested_size);
+ (*p_max_size) = MAX((*p_max_size), requested_size);
+ #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+ break;
+ }
+ memory_index += block_size;
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Memory reservation result %d, memory %p, size %d!",
+ err_code,
+ (uint32_t)(*pp_buffer),
+ (*p_size));
+
+ #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ nrf_mem_diagnose();
+ #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+ }
+
+ MM_MUTEX_UNLOCK();
+
+ NRF_LOG_DEBUG("<< %s %p, result 0x%08lX.", (uint32_t)__func__,
+ (uint32_t)(*pp_buffer), err_code);
+
+ return err_code;
+}
+
+
+void * nrf_malloc(uint32_t size)
+{
+ uint8_t * buffer = NULL;
+ uint32_t allocated_size = size;
+
+ uint32_t retval = nrf_mem_reserve(&buffer, &allocated_size);
+
+ if (retval != NRF_SUCCESS)
+ {
+ buffer = NULL;
+ }
+
+ return buffer;
+}
+
+
+void * nrf_calloc(uint32_t count, uint32_t size)
+{
+ uint8_t * buffer = NULL;
+ uint32_t allocated_size = (size * count);
+
+ NRF_LOG_DEBUG("[%s]: Requested size %d, count %d", (uint32_t)__func__, allocated_size, count);
+
+ uint32_t retval = nrf_mem_reserve(&buffer, &allocated_size);
+ if (retval == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("[%s]: buffer %p, total size %d", (uint32_t)__func__, (uint32_t)buffer, allocated_size);
+ memset(buffer,0, allocated_size);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("[%s]: Failed to allocate memory %d", (uint32_t)__func__, allocated_size);
+ buffer = NULL;
+ }
+
+ return buffer;
+}
+
+
+void nrf_free(void * p_mem)
+{
+ VERIFY_MODULE_INITIALIZED_VOID();
+ NULL_PARAM_CHECK_VOID(p_mem);
+
+ NRF_LOG_DEBUG(">> %s %p.", (uint32_t)__func__, (uint32_t)p_mem);
+
+ MM_MUTEX_LOCK();
+
+ uint32_t index;
+ uint32_t memory_index = 0;
+
+ for (index = 0; index < TOTAL_BLOCK_COUNT; index++)
+ {
+ if (&m_memory[memory_index] == p_mem)
+ {
+ // Found a free block of memory, assign.
+ NRF_LOG_DEBUG("<< Freeing block %d.", index);
+ block_init(index);
+ break;
+ }
+ memory_index += get_block_size(index);
+ }
+
+ MM_MUTEX_UNLOCK();
+
+ NRF_LOG_DEBUG("<< %s.", (uint32_t)__func__);
+ return;
+}
+
+
+void * nrf_realloc(void * p_mem, uint32_t size)
+{
+ return p_mem;
+}
+
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+/**@brief Function to format and print information with respect to each block.
+ *
+ * @details Internal function that formats and prints information related to the block category
+ * identified by 'block_cat'. This function also appends the number of bytes in use to
+ * p_mem_in_use based on current count of block in the category.
+ *
+ * @param[in] block_cat Identifies the category of block.
+ * @param[out] p_mem_in_use Updates the memory in use based on count in use.
+ */
+void print_block_info(uint32_t block_cat, uint32_t * p_mem_in_use)
+{
+ #define PRINT_COLUMN_WIDTH 13
+ #define PRINT_BUFFER_SIZE 80
+ #define ASCII_VALUE_FOR_SPACE 32
+
+ char print_buffer[PRINT_BUFFER_SIZE];
+ const uint32_t total_count = (m_block_start[block_cat] + m_block_count[block_cat]);
+ uint32_t in_use = 0;
+ uint32_t num_of_blocks = 0;
+ uint32_t index = m_block_start[block_cat];
+ uint32_t column_number;
+
+ // No statistic provided in case block category is not included.
+ if (m_block_count[block_cat] != 0)
+ {
+ memset(print_buffer, ASCII_VALUE_FOR_SPACE, PRINT_BUFFER_SIZE);
+
+ for (; index < total_count; index++)
+ {
+ if (is_block_free(index) == false)
+ {
+ num_of_blocks++;
+ in_use += m_block_size[block_cat];
+ }
+ }
+
+ column_number = 0;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %s",
+ m_block_desc_str[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_block_size[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_block_count[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ num_of_blocks);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_min_size[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_max_size[block_cat]);
+
+ column_number++;
+ const uint32_t column_end = (column_number * PRINT_COLUMN_WIDTH);
+
+ for (int j = 0; j < column_end; j ++)
+ {
+ if (print_buffer[j] == 0)
+ {
+ print_buffer[j] = 0x20;
+ }
+ }
+ snprintf(&print_buffer[column_end], 2, "|");
+
+ NRF_LOG_BYTES_DEBUG(print_buffer, strlen(print_buffer));
+
+ (*p_mem_in_use) += in_use;
+ }
+}
+
+
+void nrf_mem_diagnose(void)
+{
+ uint32_t in_use = 0;
+
+ NRF_LOG_DEBUG("");
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+ NRF_LOG_DEBUG("| Block | Size | Total | In Use | Min Alloc | Max Alloc |");
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+
+ print_block_info(BLOCK_CAT_XXS, &in_use);
+ print_block_info(BLOCK_CAT_XS, &in_use);
+ print_block_info(BLOCK_CAT_SMALL, &in_use);
+ print_block_info(BLOCK_CAT_MEDIUM, &in_use);
+ print_block_info(BLOCK_CAT_LARGE, &in_use);
+ print_block_info(BLOCK_CAT_XL, &in_use);
+ print_block_info(BLOCK_CAT_XXL, &in_use);
+
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+ NRF_LOG_DEBUG("| Total | %d | %d | %d",
+ TOTAL_MEMORY_SIZE, TOTAL_BLOCK_COUNT,in_use);
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+}
+
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+/** @} */
+#endif //NRF_MODULE_ENABLED(MEM_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h
new file mode 100644
index 0000000..5030578
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup mem_manager Memory Manager
+ * @{
+ * @ingroup app_common
+ * @brief Memory Manager for the @nRFXX SDK
+ *
+ * @details This module allows for dynamic use of memory. Currently,
+ * this module can be used only to allocate and free memory in the RAM.
+ *
+ * The Memory Manager manages static memory blocks of fixed sizes. These blocks can be requested for
+ * usage, and freed when the application no longer needs them. A maximum of seven block categories
+ * can be managed by the module. These block categories are identified by xxsmall, xmall, small,
+ * medium, large, xlarge, and xxlarge. They are ordered in increasing block sizes.
+ * The size and the count of each of the block categories can be configured based on the application
+ * requirements in the configuration file @c sdk_config.h.
+ * To use fewer than seven buffer pools, do not define the count for the unwanted block
+ * or explicitly set it to zero. At least one block category must be configured
+ * for this module to function as expected.
+ */
+
+#ifndef MEM_MANAGER_H__
+#define MEM_MANAGER_H__
+
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Initializes Memory Manager.
+ *
+ * @details API to initialize the Memory Manager. Always call this API before using any of the other
+ * APIs of the module. This API should be called only once.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * Otherwise, an error code that indicates the reason for the failure is returned.
+ *
+ * @warning If this API fails, the application shall not proceed with using other APIs of this
+ * module.
+ */
+uint32_t nrf_mem_init(void);
+
+
+/**@brief Reserves a block of memory for the application.
+ *
+ * @details API to request a contiguous memory block of the given length. If
+ * the memory allocation succeeds, pp_buffer points to the memory block. If
+ * the memory allocation fails, pp_buffer points to NULL and the return value of
+ * the API indicates the reason for the failure. The memory block reserved using this API can
+ * be freed using the @ref nrf_free function.
+ *
+ * @param[out] pp_buffer Pointer to the allocated memory block if memory allocation
+ * succeeds; otherwise points to NULL.
+ * @param[inout] p_size Requested memory size. This parameter returns the actual size
+ * allocated. If the procedure was successful, the actual size
+ * returned is always greater than or equal to requested size,
+ * never less.
+ *
+ * @retval NRF_SUCCESS If memory was successfully allocated.
+ * Otherwise, an error code indicating the reason for failure.
+ * @retval NRF_ERROR_INVALID_PARAM If the requested memory size is zero or greater than the
+ * largest memory block that the module is configured to
+ * support.
+ * @retval NRF_ERROR_NO_MEM If there is no memory available of the requested size.
+ */
+uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size);
+
+
+/**@brief 'malloc' styled memory allocation function.
+ *
+ * @details API to allocate memory, same as nrf_mem_reserve but uses malloc signature.
+ *
+ * @param[in] size Requested memory size.
+ *
+ * @retval Valid memory location if the procedure was successful, else, NULL.
+ */
+void * nrf_malloc(uint32_t size);
+
+
+/**@brief 'calloc' styled memory allocation function.
+ *
+ * @details API to allocate zero-initialized memory of size count*size.
+ *
+ * @param[in] nmemb Number of elements of 'size' bytes.
+ * @param[in] size Size of each element allocated.
+ *
+ * @retval Valid, zero-initialized memory location if the procedure was successful, else, NULL.
+ */
+void * nrf_calloc(uint32_t nmemb, uint32_t size);
+
+
+/**@brief Free allocated memory - standard 'free' styles API.
+ *
+ * @details API to resubmit memory allocated, same in functionality nrf_free.
+ *
+ * @param[out] p_buffer Pointer to the memory block that is being freed.
+ */
+void nrf_free(void * p_buffer);
+
+
+/**@brief Memory reallocation (trim) function.
+ *
+ * @details API to reallocate memory or to trim it. Trim is mentioned here to avoid use of API to
+ * request memory size larger than original memory allocated.
+ *
+ * @param[in] p_buffer Pointer to the memory block that needs to be trimmed.
+ * @param[in] size Size of memory at the beginning of the buffer to be left untrimmed.
+ *
+ * @retval Pointer to memory location with trimmed size, else, NULL.
+ */
+void * nrf_realloc(void *p_buffer, uint32_t size);
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+/**@brief Function to print statistics related to memory blocks managed by memory manager.
+ *
+ * @details This API prints information with respects to each block function, including size, total
+ * block count, number of blocks in use at the time of printing, smallest memory size
+ * allocated in the block and the largest one. This API is intended to help developers
+ * tune the block sizes to make optimal use of memory for the application.
+ * This functionality is never needed in final application and therefore, is disabled by
+ * default.
+ */
+void nrf_mem_diagnose(void);
+
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MEM_MANAGER_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h
new file mode 100644
index 0000000..2e1b553
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ * @defgroup nrf_mtx nRF Mutex
+ * @{
+ * @ingroup app_common
+ * @brief Mutex used for protecting resources.
+ *
+ * This module provides a mutex that can be used to ensure only one context may enter a critical
+ * section holding the lock.
+ */
+#ifndef NRF_MTX_H__
+#define NRF_MTX_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "nrf_assert.h"
+
+#define NRF_MTX_LOCKED 1
+#define NRF_MTX_UNLOCKED 0
+
+/**
+ * @brief Mutex data type.
+ *
+ * All fields in this struct are internal, and should never be modified outside of the nrf_mtx_*
+ * functions.
+ */
+typedef nrf_atomic_u32_t nrf_mtx_t;
+
+/**
+ * @brief Initialize mutex.
+ *
+ * This function _must_ be called before nrf_mtx_trylock() and nrf_mtx_unlock() functions.
+ *
+ * @param[in, out] p_mtx The mutex to be initialized.
+ */
+__STATIC_INLINE void nrf_mtx_init(nrf_mtx_t * p_mtx);
+
+
+/**
+ * @brief Destroy mutex.
+ *
+ * This function can be used in abort scenarios or when the mutex is no longer to be used.
+ *
+ * @param[in] p_mtx The mutex to be destroy.
+ */
+__STATIC_INLINE void nrf_mtx_destroy(nrf_mtx_t * p_mtx);
+
+/**
+ * @brief Try to lock a mutex.
+ *
+ * If the mutex is already held by another context, this function will return immediately.
+ *
+ * @param[in, out] p_mtx The mutex to be locked.
+ * @return true if lock was acquired, false if not
+ */
+__STATIC_INLINE bool nrf_mtx_trylock(nrf_mtx_t * p_mtx);
+
+/**
+ * @brief Unlock a mutex.
+ *
+ * This function _must_ only be called when holding the lock. Unlocking a mutex which you do not
+ * hold will give undefined behavior.
+ *
+ * @note Unlock must happen from the same context as the one used to lock the mutex.
+ *
+ * @param[in, out] p_mtx The mutex to be unlocked.
+ */
+__STATIC_INLINE void nrf_mtx_unlock(nrf_mtx_t * p_mtx);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_mtx_init(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+
+ *p_mtx = NRF_MTX_UNLOCKED;
+ __DMB();
+}
+
+__STATIC_INLINE void nrf_mtx_destroy(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+
+ // Add memory barrier to ensure that any memory operations protected by the mutex complete
+ // before the mutex is destroyed.
+ __DMB();
+
+ *p_mtx = NRF_MTX_UNLOCKED;
+}
+
+__STATIC_INLINE bool nrf_mtx_trylock(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+
+ uint32_t old_val = nrf_atomic_u32_fetch_store(p_mtx, NRF_MTX_LOCKED);
+
+ // Add memory barrier to ensure that the mutex is locked before any memory operations protected
+ // by the mutex are started.
+ __DMB();
+
+ return (old_val == NRF_MTX_UNLOCKED);
+}
+
+__STATIC_INLINE void nrf_mtx_unlock(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+ ASSERT(*p_mtx == NRF_MTX_LOCKED);
+
+ // Add memory barrier to ensure that any memory operations protected by the mutex complete
+ // before the mutex is unlocked.
+ __DMB();
+
+ *p_mtx = NRF_MTX_UNLOCKED;
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#endif // NRF_MTX_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c
new file mode 100644
index 0000000..a549010
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c
@@ -0,0 +1,1009 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_PWM)
+#include "app_pwm.h"
+#include "nrf_drv_timer.h"
+#include "nrf_drv_ppi.h"
+#include "nrf_drv_gpiote.h"
+#include "nrf_gpiote.h"
+#include "nrf_gpio.h"
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+
+#define APP_PWM_CHANNEL_INITIALIZED 1
+#define APP_PWM_CHANNEL_UNINITIALIZED 0
+
+#define APP_PWM_CHANNEL_ENABLED 1
+#define APP_PWM_CHANNEL_DISABLED 0
+
+#define TIMER_PRESCALER_MAX 9
+#define TIMER_MAX_PULSEWIDTH_US_ON_16M 4095
+
+#ifndef GPIOTE_SET_CLEAR_TASKS
+#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE 2
+#endif
+#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL 2
+
+#define UNALLOCATED 0xFFFFFFFFUL
+#define BUSY_STATE_CHANGING 0xFE
+#define BUSY_STATE_IDLE 0xFF
+
+#define PWM_MAIN_CC_CHANNEL 2
+#define PWM_SECONDARY_CC_CHANNEL 3
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+static bool m_use_ppi_delay_workaround;
+#endif
+
+
+/**
+ * @brief PWM busy status
+ *
+ * Stores the number of a channel being currently updated.
+ *
+ */
+static volatile uint8_t m_pwm_busy[TIMER_COUNT];
+
+
+/**
+ * @brief New duty cycle value
+ *
+ * When the channel duty cycle reaches this value, the update process is complete.
+ */
+static volatile uint32_t m_pwm_target_value[TIMER_COUNT];
+
+
+/**
+ * @brief PWM ready counter
+ *
+ * The value in this counter is decremented in every PWM cycle after initiating the update.
+ * If an event handler function was specified by the user, it is being called
+ * after two cycle events (at least one full PWM cycle).
+ */
+volatile uint8_t m_pwm_ready_counter[TIMER_COUNT][APP_PWM_CHANNELS_PER_INSTANCE];
+
+/**
+ * @brief Pointers to instances
+ *
+ * This array connects any active timer instance number with the pointer to the PWM instance.
+ * It is used by the interrupt runtime.
+ */
+static const app_pwm_t * m_instances[TIMER_COUNT];
+
+// Macros for getting the polarity of given instance/channel.
+#define POLARITY_ACTIVE(INST,CH) (( ((INST)->p_cb)->channels_cb[(CH)].polarity == \
+ APP_PWM_POLARITY_ACTIVE_LOW)?(0):(1))
+#define POLARITY_INACTIVE(INST,CH) (( ((INST)->p_cb)->channels_cb[(CH)].polarity == \
+ APP_PWM_POLARITY_ACTIVE_LOW)?(1):(0))
+
+//lint -save -e534
+
+
+/**
+ * @brief Workaround for PAN-73.
+ *
+ * @param[in] timer Timer.
+ * @param[in] enable Enable or disable.
+ */
+static void pan73_workaround(NRF_TIMER_Type * p_timer, bool enable)
+{
+#ifndef GPIOTE_SET_CLEAR_TASKS
+ if (p_timer == NRF_TIMER0)
+ {
+ *(uint32_t *)0x40008C0C = (enable ? 1 : 0);
+ }
+ else if (p_timer == NRF_TIMER1)
+ {
+ *(uint32_t *)0x40009C0C = (enable ? 1 : 0);
+ }
+ else if (p_timer == NRF_TIMER2)
+ {
+ *(uint32_t *)0x4000AC0C = (enable ? 1 : 0);
+ }
+#else
+ UNUSED_PARAMETER(p_timer);
+ UNUSED_PARAMETER(enable);
+#endif
+}
+
+bool app_pwm_busy_check(app_pwm_t const * const p_instance)
+{
+ uint8_t busy_state = (m_pwm_busy[p_instance->p_timer->instance_id]);
+ bool busy = true;
+ if (busy_state != BUSY_STATE_IDLE)
+ {
+ if (busy_state != BUSY_STATE_CHANGING)
+ {
+ if (nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) busy_state)
+ == m_pwm_target_value[p_instance->p_timer->instance_id])
+ {
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ busy = false;
+ }
+ }
+ }
+ else
+ {
+ busy = false;
+ }
+ return busy;
+}
+
+
+/**
+ * @brief Function for enabling the IRQ for a given PWM instance.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_irq_enable(app_pwm_t const * const p_instance)
+{
+ nrf_drv_timer_compare_int_enable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL);
+}
+
+
+/**
+ * @brief Function for disabling the IRQ for a given PWM instance.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_irq_disable(app_pwm_t const * const p_instance)
+{
+ nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL);
+}
+
+#ifndef GPIOTE_SET_CLEAR_TASKS
+/**
+ * @brief Function for disabling PWM channel PPI.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_channel_ppi_disable(app_pwm_t const * const p_instance, uint8_t channel)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[1]);
+}
+
+
+/**
+ * @brief Function for disabling PWM PPI.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_ppi_disable(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channels[1]);
+}
+#endif
+
+/**
+ * @brief This function is called on interrupt after duty set.
+ *
+ * @param[in] timer Timer used by PWM.
+ * @param[in] timer_instance_id Timer index.
+ */
+void pwm_ready_tick(nrf_timer_event_t event_type, void * p_context)
+{
+ uint32_t timer_instance_id = (uint32_t)p_context;
+ uint8_t disable = 1;
+
+ for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel)
+ {
+ if (m_pwm_ready_counter[timer_instance_id][channel])
+ {
+ --m_pwm_ready_counter[timer_instance_id][channel];
+ if (!m_pwm_ready_counter[timer_instance_id][channel])
+ {
+ app_pwm_cb_t * p_cb = m_instances[timer_instance_id]->p_cb;
+ p_cb->p_ready_callback(timer_instance_id);
+ }
+ else
+ {
+ disable = 0;
+ }
+ }
+ }
+
+ if (disable)
+ {
+ pwm_irq_disable(m_instances[timer_instance_id]);
+ }
+}
+
+
+/**
+ * @brief Function for resource de-allocation.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+//lint -e{650}
+static void pwm_dealloc(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ nrf_drv_ppi_channel_free(p_cb->ppi_channel);
+#else
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i)
+ {
+ if (p_cb->ppi_channels[i] != (nrf_ppi_channel_t)(uint8_t)(UNALLOCATED))
+ {
+ nrf_drv_ppi_channel_free(p_cb->ppi_channels[i]);
+ }
+ }
+ if (p_cb->ppi_group != (nrf_ppi_channel_group_t)UNALLOCATED)
+ {
+ nrf_drv_ppi_group_free(p_cb->ppi_group);
+ }
+#endif //GPIOTE_SET_CLEAR_TASKS
+ for (uint8_t ch = 0; ch < APP_PWM_CHANNELS_PER_INSTANCE; ++ch)
+ {
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i)
+ {
+ if (p_cb->channels_cb[ch].ppi_channels[i] != (nrf_ppi_channel_t)UNALLOCATED)
+ {
+ nrf_drv_ppi_channel_free(p_cb->channels_cb[ch].ppi_channels[i]);
+ p_cb->channels_cb[ch].ppi_channels[i] = (nrf_ppi_channel_t)UNALLOCATED;
+ }
+ }
+ if (p_cb->channels_cb[ch].gpio_pin != UNALLOCATED)
+ {
+ nrf_drv_gpiote_out_uninit(p_cb->channels_cb[ch].gpio_pin);
+ p_cb->channels_cb[ch].gpio_pin = UNALLOCATED;
+ }
+ p_cb->channels_cb[ch].initialized = APP_PWM_CHANNEL_UNINITIALIZED;
+ }
+ nrf_drv_timer_uninit(p_instance->p_timer);
+ return;
+}
+
+#ifndef GPIOTE_SET_CLEAR_TASKS
+/**
+ * @brief PWM state transition from (0%, 100%) to 0% or 100%.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_n_to_0or100(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group;
+
+ pwm_ppi_disable(p_instance);
+ nrf_drv_ppi_group_clear(p_ppigrp);
+ nrf_drv_ppi_channels_include_in_group(
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0]) |
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]),
+ p_ppigrp);
+
+ if (!ticks)
+ {
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_ppi_task_addr_group_disable_get(p_ppigrp));
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] =
+ nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel);
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+ }
+ else
+ {
+ ticks = p_cb->period;
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_ppi_task_addr_group_disable_get(p_ppigrp));
+ // Set secondary CC channel to non-zero value:
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 1, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] = 0;
+ // The captured value will be equal to 0, because timer clear on main PWM CC channel compare is enabled.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+ }
+
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]);
+
+ p_ch_cb->pulsewidth = ticks;
+ m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL;
+}
+
+
+/**
+ * @brief PWM state transition from (0%, 100%) to (0%, 100%).
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_n_to_m(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group;
+
+ pwm_ppi_disable(p_instance);
+ nrf_drv_ppi_group_clear(p_ppigrp);
+ nrf_drv_ppi_channels_include_in_group(
+ nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[0]) |
+ nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[1]),
+ p_ppigrp);
+
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, channel));
+
+
+ if (ticks + ((nrf_timer_frequency_get(p_instance->p_timer->p_reg) == NRF_TIMER_FREQ_16MHz) ? 1 : 0)
+ < p_ch_cb->pulsewidth)
+ {
+ // For lower value, we need one more transition. Timer task delay is included.
+ // If prescaler is disabled, one tick must be added because of 1 PCLK16M clock cycle delay.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL),
+ nrf_drv_gpiote_out_task_addr_get(p_ch_cb->gpio_pin));
+ }
+ else
+ {
+ nrf_drv_ppi_channel_remove_from_group(p_cb->ppi_channels[1], p_ppigrp);
+ }
+ p_ch_cb->pulsewidth = ticks;
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, ticks, false);
+ nrf_drv_ppi_group_enable(p_ppigrp);
+
+ m_pwm_target_value[p_instance->p_timer->instance_id] = ticks;
+ m_pwm_busy[p_instance->p_timer->instance_id] = channel;
+}
+
+
+/**
+ * @brief PWM state transition from 0% or 100% to (0%, 100%).
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_0or100_to_n(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group;
+ nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel);
+
+ pwm_ppi_disable(p_instance);
+ pwm_channel_ppi_disable(p_instance, channel);
+
+ nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false);
+ nrf_drv_ppi_group_clear(p_ppigrp);
+ nrf_drv_ppi_channels_include_in_group(
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0])|
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]),
+ p_ppigrp);
+
+ if (!p_ch_cb->pulsewidth)
+ {
+ // Channel is at 0%.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp));
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] =
+ nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel);
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+
+ }
+ else
+ {
+ // Channel is at 100%.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp));
+ // Set secondary CC channel to non-zero value:
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 1, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] = 0;
+ // The captured value will be equal to 0, because timer clear on main PWM CC channel compare is enabled.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+ }
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]);
+
+ p_ch_cb->pulsewidth = ticks;
+ m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL;
+}
+
+
+/**
+ * @brief PWM state transition from 0% or 100% to 0% or 100%.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_0or100_to_0or100(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel);
+
+ pwm_ppi_disable(p_instance);
+ pwm_channel_ppi_disable(p_instance, channel);
+ if (!ticks)
+ {
+ // Set to 0%.
+ nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_INACTIVE(p_instance, channel));
+ }
+ else if (ticks >= p_cb->period)
+ {
+ // Set to 100%.
+ ticks = p_cb->period;
+ nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_ACTIVE(p_instance, channel));
+ }
+ nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false);
+ p_ch_cb->pulsewidth = ticks;
+
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ return;
+}
+
+static void pwm_transition(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_instance->p_cb->channels_cb[channel];
+
+ // Pulse width change sequence:
+ if (!p_ch_cb->pulsewidth || p_ch_cb->pulsewidth >= p_cb->period)
+ {
+ // Channel is disabled (0%) or at 100%.
+ if (!ticks || ticks >= p_cb->period)
+ {
+ // Set to 0 or 100%.
+ pwm_transition_0or100_to_0or100(p_instance, channel, ticks);
+ }
+ else
+ {
+ // Other value.
+ pwm_transition_0or100_to_n(p_instance, channel, ticks);
+ }
+ }
+ else
+ {
+ // Channel is at other value.
+ if (!ticks || ticks >= p_cb->period)
+ {
+ // Disable channel (set to 0%) or set to 100%.
+ pwm_transition_n_to_0or100(p_instance, channel, ticks);
+ }
+ else
+ {
+ // Set to any other value.
+ pwm_transition_n_to_m(p_instance, channel, ticks);
+ }
+ }
+}
+#else //GPIOTE_SET_CLEAR_TASKS
+/**
+ * @brief PWM state transition.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel);
+
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channel);
+
+ if (!ticks)
+ {
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]);
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]);
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ }
+ else if (ticks >= p_cb->period)
+ {
+ ticks = p_cb->period;
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]);
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ }
+ else
+ {
+ // Set to any other value.
+ if ((p_ch_cb->pulsewidth != p_cb->period) && (p_ch_cb->pulsewidth != 0) && (ticks < p_ch_cb->pulsewidth))
+ {
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL, p_ch_cb->pulsewidth, false);
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channel,
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL),
+ p_ch_cb->polarity ? nrf_drv_gpiote_clr_task_addr_get(p_ch_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_ch_cb->gpio_pin));
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channel);
+ m_pwm_busy[p_instance->p_timer->instance_id] = channel;
+ m_pwm_target_value[p_instance->p_timer->instance_id] = ticks;
+ }
+ else
+ {
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ }
+
+ nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false);
+
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]);
+ }
+ p_ch_cb->pulsewidth = ticks;
+ return;
+}
+#endif //GPIOTE_SET_CLEAR_TASKS
+
+ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance,
+ uint8_t channel,
+ uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+
+ ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE);
+ ASSERT(p_ch_cb->initialized == APP_PWM_CHANNEL_INITIALIZED);
+
+ if (p_cb->state != NRFX_DRV_STATE_POWERED_ON)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (ticks == p_ch_cb->pulsewidth)
+ {
+ if (p_cb->p_ready_callback)
+ {
+ p_cb->p_ready_callback(p_instance->p_timer->instance_id);
+ }
+ return NRF_SUCCESS; // No action required.
+ }
+ if (app_pwm_busy_check(p_instance))
+ {
+ return NRF_ERROR_BUSY; // PPI channels for synchronization are still in use.
+ }
+
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_CHANGING;
+
+ // Set new value.
+
+ pwm_transition(p_instance, channel, ticks);
+
+ if (p_instance->p_cb->p_ready_callback)
+ {
+ //PWM ready interrupt handler will be called after one full period.
+ m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 2;
+ pwm_irq_enable(p_instance);
+ }
+ return NRF_SUCCESS;
+}
+
+uint16_t app_pwm_channel_duty_ticks_get(app_pwm_t const * const p_instance, uint8_t channel)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+
+ return p_ch_cb->pulsewidth;
+}
+
+uint16_t app_pwm_cycle_ticks_get(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ return (uint16_t)p_cb->period;
+}
+
+ret_code_t app_pwm_channel_duty_set(app_pwm_t const * const p_instance,
+ uint8_t channel, app_pwm_duty_t duty)
+{
+ uint32_t ticks = ((uint32_t)app_pwm_cycle_ticks_get(p_instance) * (uint32_t)duty) / 100UL;
+ return app_pwm_channel_duty_ticks_set(p_instance, channel, ticks);
+}
+
+
+app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint8_t channel)
+{
+ uint32_t value = ((uint32_t)app_pwm_channel_duty_ticks_get(p_instance, channel) * 100UL) \
+ / (uint32_t)app_pwm_cycle_ticks_get(p_instance);
+
+ return (app_pwm_duty_t)value;
+}
+
+
+/**
+ * @brief Function for initializing the PWM channel.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ * @param[in] pin GPIO pin number.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NO_MEM If there were not enough free resources.
+ * @retval NRF_ERROR_INVALID_STATE If the timer is already in use or initialization failed.
+ */
+static ret_code_t app_pwm_channel_init(app_pwm_t const * const p_instance, uint8_t channel,
+ uint32_t pin, app_pwm_polarity_t polarity)
+{
+ ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE);
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_channel_cb = &p_cb->channels_cb[channel];
+
+ if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_channel_cb->pulsewidth = 0;
+ p_channel_cb->polarity = polarity;
+ ret_code_t err_code;
+
+ /* GPIOTE setup: */
+ nrf_drv_gpiote_out_config_t out_cfg = GPIOTE_CONFIG_OUT_TASK_TOGGLE( POLARITY_INACTIVE(p_instance, channel) );
+ err_code = nrf_drv_gpiote_out_init((nrf_drv_gpiote_pin_t)pin,&out_cfg);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ p_cb->channels_cb[channel].gpio_pin = pin;
+
+ // Set output to inactive state.
+ if (polarity)
+ {
+ nrf_gpio_pin_clear(pin);
+ }
+ else
+ {
+ nrf_gpio_pin_set(pin);
+ }
+
+ /* PPI setup: */
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i)
+ {
+ if (nrf_drv_ppi_channel_alloc(&p_channel_cb->ppi_channels[i]) != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NO_MEM; // Resource de-allocation is done by callee.
+ }
+ }
+
+ nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[1]);
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ uint32_t deactivate_task_addr = polarity ? nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin);
+ uint32_t activate_task_addr = polarity ? nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin);
+
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ deactivate_task_addr);
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ activate_task_addr);
+#else //GPIOTE_SET_CLEAR_TASKS
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin));
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin));
+#endif //GPIOTE_SET_CLEAR_TASKS
+ p_channel_cb->initialized = APP_PWM_CHANNEL_INITIALIZED;
+ m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for calculating target timer frequency, which will allow to set given period length.
+ *
+ * @param[in] period_us Desired period in microseconds.
+ *
+ * @retval Timer frequency.
+ */
+__STATIC_INLINE nrf_timer_frequency_t pwm_calculate_timer_frequency(uint32_t period_us)
+{
+ uint32_t f = (uint32_t) NRF_TIMER_FREQ_16MHz;
+ uint32_t min = (uint32_t) NRF_TIMER_FREQ_31250Hz;
+
+ while ((period_us > TIMER_MAX_PULSEWIDTH_US_ON_16M) && (f < min))
+ {
+ period_us >>= 1;
+ ++f;
+ }
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ if ((m_use_ppi_delay_workaround) && (f == (uint32_t) NRF_TIMER_FREQ_16MHz))
+ {
+ f = (uint32_t) NRF_TIMER_FREQ_8MHz;
+ }
+#endif // GPIOTE_SET_CLEAR_TASKS
+
+ return (nrf_timer_frequency_t) f;
+}
+
+
+ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config,
+ app_pwm_callback_t p_ready_callback)
+{
+ ASSERT(p_instance);
+
+ if (!p_config)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ uint32_t err_code = nrf_drv_ppi_init();
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+
+ if (!nrf_drv_gpiote_is_init())
+ {
+ err_code = nrf_drv_gpiote_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
+ {
+ m_use_ppi_delay_workaround = false;
+ }
+ else
+ {
+ m_use_ppi_delay_workaround = true;
+ }
+#endif
+
+ // Innitialize resource status:
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ p_cb->ppi_channel = (nrf_ppi_channel_t)UNALLOCATED;
+#else
+ p_cb->ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->ppi_group = (nrf_ppi_channel_group_t)UNALLOCATED;
+#endif //GPIOTE_SET_CLEAR_TASKS
+
+ for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i)
+ {
+ p_cb->channels_cb[i].initialized = APP_PWM_CHANNEL_UNINITIALIZED;
+ p_cb->channels_cb[i].ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->channels_cb[i].ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->channels_cb[i].gpio_pin = UNALLOCATED;
+ }
+
+ // Allocate PPI channels and groups:
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channel) != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return NRF_ERROR_NO_MEM;
+ }
+#else //GPIOTE_SET_CLEAR_TASKS
+ if (nrf_drv_ppi_group_alloc(&p_cb->ppi_group) != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i)
+ {
+ if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channels[i]) != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+#endif //GPIOTE_SET_CLEAR_TASKS
+ // Initialize channels:
+ for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i)
+ {
+ if (p_config->pins[i] != APP_PWM_NOPIN)
+ {
+ err_code = app_pwm_channel_init(p_instance, i, p_config->pins[i], p_config->pin_polarity[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return err_code;
+ }
+ app_pwm_channel_duty_ticks_set(p_instance, i, 0);
+ }
+ }
+
+ // Initialize timer:
+ nrf_timer_frequency_t timer_freq = pwm_calculate_timer_frequency(p_config->period_us);
+ nrf_drv_timer_config_t timer_cfg = {
+ .frequency = timer_freq,
+ .mode = NRF_TIMER_MODE_TIMER,
+ .bit_width = NRF_TIMER_BIT_WIDTH_16,
+ .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
+ .p_context = (void *) (uint32_t) p_instance->p_timer->instance_id
+ };
+ err_code = nrf_drv_timer_init(p_instance->p_timer, &timer_cfg,
+ pwm_ready_tick);
+ if (err_code != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return err_code;
+ }
+
+ uint32_t ticks = nrf_drv_timer_us_to_ticks(p_instance->p_timer, p_config->period_us);
+ p_cb->period = ticks;
+ nrf_drv_timer_clear(p_instance->p_timer);
+ nrf_drv_timer_extended_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_MAIN_CC_CHANNEL,
+ ticks, NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true);
+ nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL);
+
+ p_cb->p_ready_callback = p_ready_callback;
+ m_instances[p_instance->p_timer->instance_id] = p_instance;
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ p_cb->state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+void app_pwm_enable(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ for (uint32_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel)
+ {
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0;
+ if (p_ch_cb->initialized)
+ {
+ nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_INACTIVE(p_instance, channel));
+ nrf_drv_gpiote_out_task_enable(p_ch_cb->gpio_pin);
+ p_ch_cb->pulsewidth = 0;
+ }
+ }
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+
+ pan73_workaround(p_instance->p_timer->p_reg, true);
+
+ nrf_drv_timer_clear(p_instance->p_timer);
+ nrf_drv_timer_enable(p_instance->p_timer);
+
+ p_cb->state = NRFX_DRV_STATE_POWERED_ON;
+ return;
+}
+
+
+void app_pwm_disable(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ nrf_drv_timer_disable(p_instance->p_timer);
+ pwm_irq_disable(p_instance);
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channel);
+#else
+ for (uint8_t ppi_channel = 0; ppi_channel < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++ppi_channel)
+ {
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channels[ppi_channel]);
+ }
+#endif //GPIOTE_SET_CLEAR_TASKS
+
+ for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel)
+ {
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ if (p_ch_cb->initialized)
+ {
+ uint8_t polarity = POLARITY_INACTIVE(p_instance, channel);
+ if (polarity)
+ {
+ nrf_gpio_pin_set(p_ch_cb->gpio_pin);
+ }
+ else
+ {
+ nrf_gpio_pin_clear(p_ch_cb->gpio_pin);
+ }
+ nrf_drv_gpiote_out_task_disable(p_ch_cb->gpio_pin);
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]);
+ }
+ }
+
+ pan73_workaround(p_instance->p_timer->p_reg, false);
+
+ p_cb->state = NRFX_DRV_STATE_INITIALIZED;
+ return;
+}
+
+
+ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ if (p_cb->state == NRFX_DRV_STATE_POWERED_ON)
+ {
+ app_pwm_disable(p_instance);
+ }
+ else if (p_cb->state == NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ pwm_dealloc(p_instance);
+
+ p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
+ return NRF_SUCCESS;
+}
+
+
+//lint -restore
+#endif //NRF_MODULE_ENABLED(APP_PWM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h
new file mode 100644
index 0000000..3be066b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h
@@ -0,0 +1,338 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup app_pwm Pulse-width modulation (PWM)
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for generating a pulse-width modulated output signal.
+ *
+ * @details This module provides a PWM implementation using timers, GPIOTE, and PPI.
+ *
+ * Resource usage:
+ * - 2 PPI channels per instance + 2 PPI channels per PWM channel.
+ * - 1 PPI group per instance.
+ * - 1 GPIOTE channel per PWM channel.
+ *
+ * For example, a PWM instance with two channels will consume 2 + 4 PPI channels, 1 PPI group, and 2 GPIOTE channels.
+ *
+ * The maximum number of PWM channels per instance is 2.
+ */
+
+#ifndef APP_PWM_H__
+#define APP_PWM_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_drv_timer.h"
+#include "nrf_drv_ppi.h"
+#include "nrf_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(GPIOTE_FEATURE_SET_PRESENT) && defined(GPIOTE_FEATURE_CLR_PRESENT)
+#define GPIOTE_SET_CLEAR_TASKS
+#endif
+
+#define APP_PWM_NOPIN 0xFFFFFFFF
+
+/** @brief Number of channels for one timer instance (fixed to 2 due to timer properties).*/
+#define APP_PWM_CHANNELS_PER_INSTANCE 2
+
+/**@brief Macro for creating a PWM instance. */
+#define APP_PWM_INSTANCE(name, num) \
+ const nrf_drv_timer_t m_pwm_##name##_timer = NRF_DRV_TIMER_INSTANCE(num); \
+ app_pwm_cb_t m_pwm_##name##_cb; \
+ /*lint -e{545}*/ \
+ const app_pwm_t name = { \
+ .p_cb = &m_pwm_##name##_cb, \
+ .p_timer = &m_pwm_##name##_timer, \
+ }
+
+
+/**@brief PWM instance default configuration (1 channel). */
+#define APP_PWM_DEFAULT_CONFIG_1CH(period_in_us, pin) \
+ { \
+ .pins = {pin, APP_PWM_NOPIN}, \
+ .pin_polarity = {APP_PWM_POLARITY_ACTIVE_LOW, APP_PWM_POLARITY_ACTIVE_LOW}, \
+ .num_of_channels = 1, \
+ .period_us = period_in_us \
+ }
+
+/**@brief PWM instance default configuration (2 channels). */
+#define APP_PWM_DEFAULT_CONFIG_2CH(period_in_us, pin0, pin1) \
+ { \
+ .pins = {pin0, pin1}, \
+ .pin_polarity = {APP_PWM_POLARITY_ACTIVE_LOW, APP_PWM_POLARITY_ACTIVE_LOW}, \
+ .num_of_channels = 2, \
+ .period_us = period_in_us \
+ }
+
+typedef uint16_t app_pwm_duty_t;
+
+/**
+ * @brief PWM callback that is executed when a PWM duty change has been completed.
+ *
+ * @param[in] pwm_id PWM instance ID.
+ */
+typedef void (* app_pwm_callback_t)(uint32_t);
+
+/**
+ * @brief Channel polarity.
+ */
+typedef enum
+{
+ APP_PWM_POLARITY_ACTIVE_LOW = 0,
+ APP_PWM_POLARITY_ACTIVE_HIGH = 1
+} app_pwm_polarity_t;
+
+/**@brief PWM configuration structure used for initialization. */
+typedef struct
+{
+ uint32_t pins[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Pins configured as PWM output.
+ app_pwm_polarity_t pin_polarity[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Polarity of active state on pin.
+ uint32_t num_of_channels; //!< Number of channels that can be used.
+ uint32_t period_us; //!< PWM signal output period to configure (in microseconds).
+} app_pwm_config_t;
+
+
+/**
+ * @cond (NODOX)
+ * @defgroup app_pwm_internal Auxiliary internal types declarations
+ * @{
+ * @internal
+ *
+ * @brief Module for internal usage inside the library only
+ *
+ * There are some definitions that must be included in the header file because
+ * of the way the library is set up. In this way, the are accessible to the user.
+ * However, any functions and variables defined here may change at any time
+ * without a warning, so you should not access them directly.
+ */
+
+ /**
+ * @brief PWM channel instance
+ *
+ * This structure holds all data needed by a single PWM channel.
+ */
+ typedef struct
+ {
+ uint32_t gpio_pin; //!< Pin that is used by this PWM channel.
+ uint32_t pulsewidth; //!< The copy of duty currently set (in ticks).
+ nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used by the PWM channel to clear and set the output.
+ app_pwm_polarity_t polarity; //!< The active state of the pin.
+ uint8_t initialized; //!< The internal information if the selected channel was initialized.
+ } app_pwm_channel_cb_t;
+
+ /**
+ * @brief Variable part of PWM instance
+ *
+ * This structure holds instance data that may change.
+ */
+ typedef struct
+ {
+ app_pwm_channel_cb_t channels_cb[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Channels data
+ uint32_t period; //!< Selected period in ticks
+ app_pwm_callback_t p_ready_callback; //!< Callback function called on PWM readiness
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ nrf_ppi_channel_t ppi_channel; //!< PPI channel used temporary while changing duty
+#else
+ nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used temporary while changing duty
+ nrf_ppi_channel_group_t ppi_group; //!< PPI group used to synchronize changes on channels
+#endif
+ nrfx_drv_state_t state; //!< Current driver status
+ } app_pwm_cb_t;
+/** @}
+ * @endcond
+ */
+
+
+/**@brief PWM instance structure. */
+typedef struct
+{
+ app_pwm_cb_t *p_cb; //!< Pointer to control block internals.
+ nrf_drv_timer_t const * const p_timer; //!< Timer used by this PWM instance.
+} app_pwm_t;
+
+/**
+ * @brief Function for checking if the PWM instance is busy updating the duty cycle.
+ *
+ * @param[in] p_instance PWM instance.
+ *
+ * @retval True If the PWM instance is ready for duty cycle changes.
+ * @retval False If a change operation is in progress.
+ */
+bool app_pwm_busy_check(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for initializing a PWM instance.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] p_config Initial configuration.
+ * @param[in] p_ready_callback Pointer to ready callback function (or NULL to disable).
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NO_MEM If there were not enough free resources.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid configuration structure was passed.
+ * @retval NRF_ERROR_INVALID_STATE If the timer/PWM is already in use or if initialization failed.
+ */
+ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config,
+ app_pwm_callback_t p_ready_callback);
+
+
+/**
+ * @brief Function for uninitializing a PWM instance and releasing the allocated resources.
+ *
+ * @param[in] p_instance PWM instance.
+ *
+ * @retval NRF_SUCCESS If uninitialization was successful.
+ * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized.
+ */
+ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for enabling a PWM instance after initialization.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+void app_pwm_enable(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for disabling a PWM instance after initialization.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+void app_pwm_disable(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for setting the PWM channel duty cycle in percents.
+ *
+ * A duty cycle change requires one full PWM clock period to finish.
+ * If another change is attempted for any channel of given instance before
+ * the current change is complete, the new attempt will result in the error
+ * NRF_ERROR_BUSY.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ * @param[in] duty Duty cycle (0 - 100).
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_BUSY If the PWM is not ready yet.
+ * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized.
+ *
+ */
+ret_code_t app_pwm_channel_duty_set(app_pwm_t const * const p_instance,
+ uint8_t channel, app_pwm_duty_t duty);
+
+/**
+ * @brief Function for retrieving the PWM channel duty cycle in percents.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ *
+ * @return Duty cycle value.
+ */
+app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint8_t channel);
+
+
+/**
+ * @name Functions accessing values in ticks
+ *
+ * Auxiliary functions that allow to get values in actual timer ticks.
+ * @{
+ */
+
+ /**
+ * @brief Function for setting PWM channel duty cycle in clock ticks.
+ *
+ * @note Duty cycle changes require one full PWM clock period to finish.
+ * Until that, the next change attempt (for any channel of given instance)
+ * will result in an NRF_ERROR_BUSY error.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ * @param[in] ticks Number of PWM clock ticks.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_BUSY If PWM is not ready yet.
+ * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized.
+ */
+ ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance,
+ uint8_t channel,
+ uint16_t ticks);
+
+
+ /**
+ * @brief Function for retrieving the PWM channel duty cycle in ticks.
+ *
+ * This function retrieves the real, currently set duty cycle in ticks.
+ * For one full PWM cycle the value might be different than the value set by the last
+ * @ref app_pwm_channel_duty_ticks_set function call.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ *
+ * @return Number of ticks set for selected channel.
+ *
+ */
+ uint16_t app_pwm_channel_duty_ticks_get(app_pwm_t const * const p_instance, uint8_t channel);
+
+ /**
+ * @brief Function for returning the number of ticks in a whole cycle.
+ *
+ * @param[in] p_instance PWM instance.
+ *
+ * @return Number of ticks that corresponds to 100% of the duty cycle.
+ */
+ uint16_t app_pwm_cycle_ticks_get(app_pwm_t const * const p_instance);
+/** @} */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c
new file mode 100644
index 0000000..8f36d40
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c
@@ -0,0 +1,465 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_PWR_MGMT)
+
+#include "nrf_pwr_mgmt.h"
+#include "nrf.h"
+#include "nrf_mtx.h"
+#include "nrf_power.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+#include "nrf_log_ctrl.h"
+#include "app_util_platform.h"
+
+#define NRF_LOG_MODULE_NAME pwr_mgmt
+#if NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_PWR_MGMT_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_PWR_MGMT_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_PWR_MGMT_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifdef SOFTDEVICE_PRESENT
+ #include "nrf_soc.h"
+ #include "nrf_sdh.h"
+#endif // SOFTDEVICE_PRESENT
+
+
+#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+ #if (APP_SCHEDULER_ENABLED != 1)
+ #error "APP_SCHEDULER is required."
+ #endif
+ #include "app_scheduler.h"
+#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+
+
+// Create section "pwr_mgmt_data".
+NRF_SECTION_SET_DEF(pwr_mgmt_data,
+ nrf_pwr_mgmt_shutdown_handler_t,
+ NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT);
+
+static nrf_pwr_mgmt_evt_t m_pwr_mgmt_evt; /**< Event type which will be passed to the shutdown
+ handlers.*/
+static nrf_mtx_t m_sysoff_mtx; /**< Module API lock.*/
+static bool m_shutdown_started; /**< True if application started the shutdown preparation. */
+static nrf_section_iter_t m_handlers_iter; /**< Shutdown handlers iterator. */
+
+#if (NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED && __FPU_PRESENT)
+ #define PWR_MGMT_FPU_SLEEP_PREPARE() pwr_mgmt_fpu_sleep_prepare()
+
+ __STATIC_INLINE void pwr_mgmt_fpu_sleep_prepare(void)
+ {
+ uint32_t fpscr;
+ CRITICAL_REGION_ENTER();
+ fpscr = __get_FPSCR();
+ /*
+ * Clear FPU exceptions.
+ * Without this step, the FPU interrupt is marked as pending,
+ * preventing system from sleeping. Exceptions cleared:
+ * - IOC - Invalid Operation cumulative exception bit.
+ * - DZC - Division by Zero cumulative exception bit.
+ * - OFC - Overflow cumulative exception bit.
+ * - UFC - Underflow cumulative exception bit.
+ * - IXC - Inexact cumulative exception bit.
+ * - IDC - Input Denormal cumulative exception bit.
+ */
+ __set_FPSCR(fpscr & ~0x9Fu);
+ __DMB();
+ NVIC_ClearPendingIRQ(FPU_IRQn);
+ CRITICAL_REGION_EXIT();
+
+ /*
+ * Assert no critical FPU exception is signaled:
+ * - IOC - Invalid Operation cumulative exception bit.
+ * - DZC - Division by Zero cumulative exception bit.
+ * - OFC - Overflow cumulative exception bit.
+ */
+ ASSERT((fpscr & 0x07) == 0);
+ }
+#else
+ #define PWR_MGMT_FPU_SLEEP_PREPARE()
+#endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED
+
+
+#if NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED
+ #undef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+ #define PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+
+ #include "nrf_gpio.h"
+ #define PWR_MGMT_DEBUG_PINS_INIT() pwr_mgmt_debug_pins_init()
+ #define PWR_MGMT_DEBUG_PIN_CLEAR() nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN)
+ #define PWR_MGMT_DEBUG_PIN_SET() nrf_gpio_pin_set(NRF_PWR_MGMT_SLEEP_DEBUG_PIN)
+
+ __STATIC_INLINE void pwr_mgmt_debug_pins_init(void)
+ {
+ nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN);
+ nrf_gpio_cfg_output(NRF_PWR_MGMT_SLEEP_DEBUG_PIN);
+ }
+
+#else
+ #define PWR_MGMT_DEBUG_PIN_CLEAR()
+ #define PWR_MGMT_DEBUG_PIN_SET()
+ #define PWR_MGMT_DEBUG_PINS_INIT()
+#endif
+
+
+#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+ #undef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+ #define PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+
+ #undef PWR_MGMT_TIMER_REQUIRED
+ #define PWR_MGMT_TIMER_REQUIRED
+ #include "app_timer.h"
+
+ #define PWR_MGMT_CPU_USAGE_MONITOR_INIT() pwr_mgmt_cpu_usage_monitor_init()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_UPDATE() pwr_mgmt_cpu_usage_monitor_update()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY() NRF_LOG_INFO("Maximum CPU usage: %u%%", \
+ m_max_cpu_usage)
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER() \
+ { \
+ uint32_t sleep_start = app_timer_cnt_get()
+
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT() \
+ uint32_t sleep_end = app_timer_cnt_get(); \
+ uint32_t sleep_duration; \
+ sleep_duration = app_timer_cnt_diff_compute(sleep_end, \
+ sleep_start); \
+ m_ticks_sleeping += sleep_duration; \
+ }
+
+ static uint32_t m_ticks_sleeping; /**< Number of ticks spent in sleep mode (__WFE()). */
+ static uint32_t m_ticks_last; /**< Number of ticks from the last CPU usage computation. */
+ static uint8_t m_max_cpu_usage; /**< Maximum observed CPU usage (0 - 100%). */
+
+ __STATIC_INLINE void pwr_mgmt_cpu_usage_monitor_init(void)
+ {
+ m_ticks_sleeping = 0;
+ m_ticks_last = 0;
+ m_max_cpu_usage = 0;
+ }
+
+ __STATIC_INLINE void pwr_mgmt_cpu_usage_monitor_update(void)
+ {
+ uint32_t delta;
+ uint32_t ticks;
+ uint8_t cpu_usage;
+
+ ticks = app_timer_cnt_get();
+ delta = app_timer_cnt_diff_compute(ticks, m_ticks_last);
+ cpu_usage = 100 * (delta - m_ticks_sleeping) / delta;
+
+ NRF_LOG_INFO("CPU Usage: %u%%", cpu_usage);
+ if (m_max_cpu_usage < cpu_usage)
+ {
+ m_max_cpu_usage = cpu_usage;
+ }
+
+ m_ticks_last = ticks;
+ m_ticks_sleeping = 0;
+ }
+
+#else
+ #define PWR_MGMT_CPU_USAGE_MONITOR_INIT()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_UPDATE()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT()
+#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+
+
+#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+ #undef PWR_MGMT_TIMER_REQUIRED
+ #define PWR_MGMT_TIMER_REQUIRED
+
+ #define PWR_MGMT_STANDBY_TIMEOUT_INIT() pwr_mgmt_standby_timeout_clear()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CLEAR() pwr_mgmt_standby_timeout_clear()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CHECK() pwr_mgmt_standby_timeout_check()
+
+ static uint16_t m_standby_counter; /**< Number of seconds from the last activity
+ (@ref pwr_mgmt_feed). */
+
+ __STATIC_INLINE void pwr_mgmt_standby_timeout_clear(void)
+ {
+ m_standby_counter = 0;
+ }
+
+ __STATIC_INLINE void pwr_mgmt_standby_timeout_check(void)
+ {
+ if (m_standby_counter < NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S)
+ {
+ m_standby_counter++;
+ }
+ else if (m_shutdown_started == false)
+ {
+ nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
+ }
+ }
+
+#else
+ #define PWR_MGMT_STANDBY_TIMEOUT_INIT()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CLEAR()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CHECK()
+#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+
+
+#if NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+ #undef PWR_MGMT_TIMER_REQUIRED
+ #define PWR_MGMT_TIMER_REQUIRED
+
+ #define PWR_MGMT_AUTO_SHUTDOWN_RETRY() pwr_mgmt_auto_shutdown_retry()
+
+ __STATIC_INLINE void pwr_mgmt_auto_shutdown_retry(void)
+ {
+ if (m_shutdown_started)
+ {
+ // Try to continue the shutdown procedure.
+ nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE);
+ }
+ }
+
+#else
+ #define PWR_MGMT_AUTO_SHUTDOWN_RETRY()
+#endif // NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+
+
+#ifdef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+ #define PWR_MGMT_SLEEP_INIT() pwr_mgmt_sleep_init()
+ #define PWR_MGMT_SLEEP_LOCK_ACQUIRE() CRITICAL_REGION_ENTER()
+ #define PWR_MGMT_SLEEP_LOCK_RELEASE() CRITICAL_REGION_EXIT()
+
+ __STATIC_INLINE void pwr_mgmt_sleep_init(void)
+ {
+ #ifdef SOFTDEVICE_PRESENT
+ ASSERT(current_int_priority_get() >= APP_IRQ_PRIORITY_LOW);
+ #endif
+ SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
+ }
+
+#else
+ #define PWR_MGMT_SLEEP_INIT()
+ #define PWR_MGMT_SLEEP_LOCK_ACQUIRE()
+ #define PWR_MGMT_SLEEP_LOCK_RELEASE()
+#endif // PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+
+
+#ifdef PWR_MGMT_TIMER_REQUIRED
+ #include "app_timer.h"
+ #define PWR_MGMT_TIMER_CREATE() pwr_mgmt_timer_create()
+
+ APP_TIMER_DEF(m_pwr_mgmt_timer); /**< Timer used by this module. */
+
+ /**@brief Handle events from m_pwr_mgmt_timer.
+ */
+ static void nrf_pwr_mgmt_timeout_handler(void * p_context)
+ {
+ PWR_MGMT_CPU_USAGE_MONITOR_UPDATE();
+ PWR_MGMT_AUTO_SHUTDOWN_RETRY();
+ PWR_MGMT_STANDBY_TIMEOUT_CHECK();
+ }
+
+ __STATIC_INLINE ret_code_t pwr_mgmt_timer_create(void)
+ {
+ ret_code_t ret_code = app_timer_create(&m_pwr_mgmt_timer,
+ APP_TIMER_MODE_REPEATED,
+ nrf_pwr_mgmt_timeout_handler);
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ return app_timer_start(m_pwr_mgmt_timer, APP_TIMER_TICKS(1000), NULL);
+ }
+#else
+ #define PWR_MGMT_TIMER_CREATE() NRF_SUCCESS
+#endif // PWR_MGMT_TIMER_REQUIRED
+
+ret_code_t nrf_pwr_mgmt_init(void)
+{
+ NRF_LOG_INFO("Init");
+
+ m_shutdown_started = false;
+ nrf_mtx_init(&m_sysoff_mtx);
+ nrf_section_iter_init(&m_handlers_iter, &pwr_mgmt_data);
+
+ PWR_MGMT_SLEEP_INIT();
+ PWR_MGMT_DEBUG_PINS_INIT();
+ PWR_MGMT_STANDBY_TIMEOUT_INIT();
+ PWR_MGMT_CPU_USAGE_MONITOR_INIT();
+
+ return PWR_MGMT_TIMER_CREATE();
+}
+
+void nrf_pwr_mgmt_run(void)
+{
+ PWR_MGMT_FPU_SLEEP_PREPARE();
+ PWR_MGMT_SLEEP_LOCK_ACQUIRE();
+ PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER();
+ PWR_MGMT_DEBUG_PIN_SET();
+
+ // Wait for an event.
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ ret_code_t ret_code = sd_app_evt_wait();
+ ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
+ UNUSED_VARIABLE(ret_code);
+ }
+ else
+#endif // SOFTDEVICE_PRESENT
+ {
+ // Wait for an event.
+ __WFE();
+ // Clear the internal event register.
+ __SEV();
+ __WFE();
+ }
+
+ PWR_MGMT_DEBUG_PIN_CLEAR();
+ PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT();
+ PWR_MGMT_SLEEP_LOCK_RELEASE();
+}
+
+void nrf_pwr_mgmt_feed(void)
+{
+ NRF_LOG_DEBUG("Feed");
+ // It does not stop started shutdown process.
+ PWR_MGMT_STANDBY_TIMEOUT_CLEAR();
+}
+
+/**@brief Function runs the shutdown procedure.
+ */
+static void shutdown_process(void)
+{
+ NRF_LOG_INFO("Shutdown started. Type %d", m_pwr_mgmt_evt);
+ // Executing all callbacks.
+ for (/* m_handlers_iter is initialized in nrf_pwr_mgmt_init(). Thanks to that each handler is
+ called only once.*/;
+ nrf_section_iter_get(&m_handlers_iter) != NULL;
+ nrf_section_iter_next(&m_handlers_iter))
+ {
+ nrf_pwr_mgmt_shutdown_handler_t * p_handler =
+ (nrf_pwr_mgmt_shutdown_handler_t *) nrf_section_iter_get(&m_handlers_iter);
+ if ((*p_handler)(m_pwr_mgmt_evt))
+ {
+ NRF_LOG_INFO("SysOff handler 0x%08X => ready", (unsigned int)*p_handler);
+ }
+ else
+ {
+ // One of the modules is not ready.
+ NRF_LOG_INFO("SysOff handler 0x%08X => blocking", (unsigned int)*p_handler);
+ return;
+ }
+ }
+
+ PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY();
+ NRF_LOG_INFO("Shutdown complete.");
+ NRF_LOG_FINAL_FLUSH();
+
+ if ((m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_RESET)
+ || (m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_DFU))
+ {
+ NVIC_SystemReset();
+ }
+ else
+ {
+ // Enter System OFF.
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ ret_code_t ret_code = sd_power_system_off();
+ ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
+ UNUSED_VARIABLE(ret_code);
+ }
+#endif // SOFTDEVICE_PRESENT
+ nrf_power_system_off();
+ }
+}
+
+#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+/**@brief Handle events from app_scheduler.
+ */
+static void scheduler_shutdown_handler(void * p_event_data, uint16_t event_size)
+{
+ UNUSED_PARAMETER(p_event_data);
+ UNUSED_PARAMETER(event_size);
+ shutdown_process();
+}
+#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+
+void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type)
+{
+ // Check if shutdown procedure is not started.
+ if (!nrf_mtx_trylock(&m_sysoff_mtx))
+ {
+ return;
+ }
+
+ if (shutdown_type != NRF_PWR_MGMT_SHUTDOWN_CONTINUE)
+ {
+ if (m_shutdown_started)
+ {
+ nrf_mtx_unlock(&m_sysoff_mtx);
+ return;
+ }
+ else
+ {
+ m_pwr_mgmt_evt = (nrf_pwr_mgmt_evt_t)shutdown_type;
+ m_shutdown_started = true;
+ }
+ }
+
+ ASSERT(m_shutdown_started);
+ NRF_LOG_INFO("Shutdown request %d", shutdown_type);
+
+#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+ ret_code_t ret_code = app_sched_event_put(NULL, 0, scheduler_shutdown_handler);
+ APP_ERROR_CHECK(ret_code);
+#else
+ shutdown_process();
+#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+
+ nrf_mtx_unlock(&m_sysoff_mtx);
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_PWR_MGMT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h
new file mode 100644
index 0000000..3f6eb56
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+ * @defgroup nrf_pwr_mgmt Power management
+ * @ingroup app_common
+ * @{
+ * @brief This module handles power management features.
+ *
+ */
+#ifndef NRF_PWR_MGMT_H__
+#define NRF_PWR_MGMT_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sdk_errors.h>
+#include "nrf_section_iter.h"
+
+/**@brief Power management shutdown types. */
+typedef enum
+{
+ NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF,
+ //!< Go to System OFF.
+
+ NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF,
+ //!< Go to System OFF and stay there.
+ /**<
+ * Useful when battery level is dangerously low, for example.
+ */
+
+ NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU,
+ //!< Go to DFU mode.
+
+ NRF_PWR_MGMT_SHUTDOWN_RESET,
+ //!< Reset chip.
+
+ NRF_PWR_MGMT_SHUTDOWN_CONTINUE
+ //!< Continue shutdown.
+ /**<
+ * This should be used by modules that block the shutdown process, when they become ready for
+ * shutdown.
+ */
+} nrf_pwr_mgmt_shutdown_t;
+
+/**@brief Shutdown event types. */
+typedef enum
+{
+ NRF_PWR_MGMT_EVT_PREPARE_WAKEUP = NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF,
+ //!< Application will prepare the wakeup mechanism.
+
+ NRF_PWR_MGMT_EVT_PREPARE_SYSOFF = NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF,
+ //!< Application will prepare to stay in System OFF state.
+
+ NRF_PWR_MGMT_EVT_PREPARE_DFU = NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU,
+ //!< Application will prepare to enter DFU mode.
+
+ NRF_PWR_MGMT_EVT_PREPARE_RESET = NRF_PWR_MGMT_SHUTDOWN_RESET,
+ //!< Application will prepare to chip reset.
+} nrf_pwr_mgmt_evt_t;
+
+/**@brief Shutdown callback.
+ * @param[in] event Type of shutdown process.
+ *
+ * @retval true System OFF / Enter DFU preparation successful. Process will be continued.
+ * @retval false System OFF / Enter DFU preparation failed. @ref NRF_PWR_MGMT_SHUTDOWN_CONTINUE
+ * should be used to continue the shutdown process.
+ */
+typedef bool (*nrf_pwr_mgmt_shutdown_handler_t)(nrf_pwr_mgmt_evt_t event);
+
+/**@brief Macro for registering a shutdown handler. Modules that want to get events
+ * from this module must register the handler using this macro.
+ *
+ * @details This macro places the handler in a section named "pwr_mgmt_data".
+ *
+ * @param[in] _handler Event handler (@ref nrf_pwr_mgmt_shutdown_handler_t).
+ * @param[in] _priority Priority of the given handler.
+ */
+#define NRF_PWR_MGMT_HANDLER_REGISTER(_handler, _priority) \
+ STATIC_ASSERT(_priority < NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT); \
+ /*lint -esym(528,*_handler_function) -esym(529,*_handler_function) : Symbol not referenced. */ \
+ NRF_SECTION_SET_ITEM_REGISTER(pwr_mgmt_data, _priority, \
+ static nrf_pwr_mgmt_shutdown_handler_t const CONCAT_2(_handler, _handler_function)) = (_handler)
+
+/**@brief Function for initializing power management.
+ *
+ * @warning Depending on configuration, this function sets SEVONPEND in System Control Block (SCB).
+ * This operation is unsafe with the SoftDevice from interrupt priority higher than SVC.
+ *
+ * @retval NRF_SUCCESS
+ */
+ret_code_t nrf_pwr_mgmt_init(void);
+
+/**@brief Function for running power management. Should run in the main loop.
+ */
+void nrf_pwr_mgmt_run(void);
+
+/**@brief Function for indicating activity.
+ *
+ * @details Call this function whenever doing something that constitutes "activity".
+ * For example, whenever sending data, call this function to indicate that the application
+ * is active and should not disconnect any ongoing communication links.
+ */
+void nrf_pwr_mgmt_feed(void);
+
+/**@brief Function for shutting down the system.
+ *
+ * @param[in] shutdown_type Type of operation.
+ *
+ * @details All callbacks will be executed prior to shutdown.
+ */
+void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type);
+
+#endif // NRF_PWR_MGMT_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c
new file mode 100644
index 0000000..9afc16c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c
@@ -0,0 +1,547 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_QUEUE)
+#include "nrf_queue.h"
+#include "app_util_platform.h"
+
+#if NRF_QUEUE_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_QUEUE_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INIT_FILTER_LEVEL NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_QUEUE_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_QUEUE_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_QUEUE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+
+NRF_SECTION_DEF(nrf_queue, nrf_queue_t);
+
+#if NRF_QUEUE_CLI_CMDS
+#include "nrf_cli.h"
+
+static void nrf_queue_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc > 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad argument count");
+ return;
+ }
+
+ uint32_t num_of_instances = NRF_SECTION_ITEM_COUNT(nrf_queue, nrf_queue_t);
+ uint32_t i;
+
+ for (i = 0; i < num_of_instances; i++)
+ {
+ const nrf_queue_t * p_instance = NRF_SECTION_ITEM_GET(nrf_queue, nrf_queue_t, i);
+
+ uint32_t element_size = p_instance->element_size;
+ uint32_t size = p_instance->size;
+ uint32_t max_util = nrf_queue_max_utilization_get(p_instance);
+ uint32_t util = nrf_queue_utilization_get(p_instance);
+ const char * p_name = p_instance->p_name;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL,
+ "%s\r\n\t- Element size:\t%d\r\n"
+ "\t- Usage:\t%u%% (%u out of %u elements)\r\n"
+ "\t- Maximum:\t%u%% (%u out of %u elements)\r\n"
+ "\t- Mode:\t\t%s\r\n\r\n",
+ p_name, element_size,
+ 100ul * util/size, util,size,
+ 100ul * max_util/size, max_util,size,
+ (p_instance->mode == NRF_QUEUE_MODE_OVERFLOW) ? "Overflow" : "No overflow");
+
+ }
+}
+// Register "queue" command and its subcommands in CLI.
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_queue_commands)
+{
+ NRF_CLI_CMD(status, NULL, "Print status of queue instances.", nrf_queue_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(queue, &nrf_queue_commands, "Commands for BALLOC management", nrf_queue_status);
+#endif //NRF_QUEUE_CLI_CMDS
+
+/**@brief Get next element index.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ * @param[in] idx Current index.
+ *
+ * @return Next element index.
+ */
+__STATIC_INLINE size_t nrf_queue_next_idx(nrf_queue_t const * p_queue, size_t idx)
+{
+ ASSERT(p_queue != NULL);
+ return (idx < p_queue->size) ? (idx + 1) : 0;
+}
+
+/**@brief Get current queue utilization. This function assumes that this process will not be interrupted.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Current queue utilization.
+ */
+__STATIC_INLINE size_t queue_utilization_get(nrf_queue_t const * p_queue)
+{
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+ return (back >= front) ? (back - front) : (p_queue->size + 1 - front + back);
+}
+
+bool nrf_queue_is_full(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+
+ return (nrf_queue_next_idx(p_queue, back) == front);
+}
+
+ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_element != NULL);
+
+ CRITICAL_REGION_ENTER();
+ bool is_full = nrf_queue_is_full(p_queue);
+
+ if (!is_full || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW))
+ {
+ // Get write position.
+ size_t write_pos = p_queue->p_cb->back;
+ p_queue->p_cb->back = nrf_queue_next_idx(p_queue, p_queue->p_cb->back);
+ if (is_full)
+ {
+ // Overwrite the oldest element.
+ NRF_LOG_INST_WARNING(p_queue->p_log, "Queue full. Overwriting oldest element.");
+ p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
+ }
+
+ // Write a new element.
+ switch (p_queue->element_size)
+ {
+ case sizeof(uint8_t):
+ ((uint8_t *)p_queue->p_buffer)[write_pos] = *((uint8_t *)p_element);
+ break;
+
+ case sizeof(uint16_t):
+ ((uint16_t *)p_queue->p_buffer)[write_pos] = *((uint16_t *)p_element);
+ break;
+
+ case sizeof(uint32_t):
+ ((uint32_t *)p_queue->p_buffer)[write_pos] = *((uint32_t *)p_element);
+ break;
+
+ case sizeof(uint64_t):
+ ((uint64_t *)p_queue->p_buffer)[write_pos] = *((uint64_t *)p_element);
+ break;
+
+ default:
+ memcpy((void *)((size_t)p_queue->p_buffer + write_pos * p_queue->element_size),
+ p_element,
+ p_queue->element_size);
+ break;
+ }
+
+ // Update utilization.
+ size_t utilization = queue_utilization_get(p_queue);
+ if (p_queue->p_cb->max_utilization < utilization)
+ {
+ p_queue->p_cb->max_utilization = utilization;
+ }
+ }
+ else
+ {
+ status = NRF_ERROR_NO_MEM;
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "pushed element 0x%08X, status:%d", p_element, status);
+ return status;
+}
+
+ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue,
+ void * p_element,
+ bool just_peek)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_element != NULL);
+
+ CRITICAL_REGION_ENTER();
+
+ if (!nrf_queue_is_empty(p_queue))
+ {
+ // Get read position.
+ size_t read_pos = p_queue->p_cb->front;
+
+ // Update next read position.
+ if (!just_peek)
+ {
+ p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
+ }
+
+ // Read element.
+ switch (p_queue->element_size)
+ {
+ case sizeof(uint8_t):
+ *((uint8_t *)p_element) = ((uint8_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ case sizeof(uint16_t):
+ *((uint16_t *)p_element) = ((uint16_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ case sizeof(uint32_t):
+ *((uint32_t *)p_element) = ((uint32_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ case sizeof(uint64_t):
+ *((uint64_t *)p_element) = ((uint64_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ default:
+ memcpy(p_element,
+ (void const *)((size_t)p_queue->p_buffer + read_pos * p_queue->element_size),
+ p_queue->element_size);
+ break;
+ }
+ }
+ else
+ {
+ status = NRF_ERROR_NOT_FOUND;
+ }
+
+ CRITICAL_REGION_EXIT();
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "%s element 0x%08X, status:%d",
+ just_peek ? "peeked" : "popped", p_element, status);
+ return status;
+}
+
+/**@brief Write elements to the queue. This function assumes that there is enough room in the queue
+ * to write the requested number of elements and that this process will not be interrupted.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_data Pointer to the buffer with elements to write.
+ * @param[in] element_count Number of elements to write.
+ */
+static void queue_write(nrf_queue_t const * p_queue, void const * p_data, uint32_t element_count)
+{
+ size_t prev_available = nrf_queue_available_get(p_queue);
+ size_t continuous = p_queue->size + 1 - p_queue->p_cb->back;
+ void * p_write_ptr = (void *)((size_t)p_queue->p_buffer
+ + p_queue->p_cb->back * p_queue->element_size);
+ if (element_count <= continuous)
+ {
+ memcpy(p_write_ptr,
+ p_data,
+ element_count * p_queue->element_size);
+
+ p_queue->p_cb->back = ((p_queue->p_cb->back + element_count) <= p_queue->size)
+ ? (p_queue->p_cb->back + element_count)
+ : 0;
+ }
+ else
+ {
+ size_t first_write_length = continuous * p_queue->element_size;
+ memcpy(p_write_ptr,
+ p_data,
+ first_write_length);
+
+ size_t elements_left = element_count - continuous;
+ memcpy(p_queue->p_buffer,
+ (void const *)((size_t)p_data + first_write_length),
+ elements_left * p_queue->element_size);
+
+ p_queue->p_cb->back = elements_left;
+ if (prev_available < element_count)
+ {
+ // Overwrite the oldest elements.
+ p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->back);
+ }
+ }
+
+ // Update utilization.
+ size_t utilization = queue_utilization_get(p_queue);
+ if (p_queue->p_cb->max_utilization < utilization)
+ {
+ p_queue->p_cb->max_utilization = utilization;
+ }
+}
+
+ret_code_t nrf_queue_write(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+ ASSERT(element_count <= p_queue->size);
+
+ if (element_count == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if ((nrf_queue_available_get(p_queue) >= element_count)
+ || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW))
+ {
+ queue_write(p_queue, p_data, element_count);
+ }
+ else
+ {
+ status = NRF_ERROR_NO_MEM;
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Write %d elements (start address: 0x%08X), status:%d",
+ element_count, p_data, status);
+ return status;
+}
+
+
+size_t nrf_queue_in(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count)
+{
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+
+ size_t req_element_count = element_count;
+
+ if (element_count == 0)
+ {
+ return 0;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW)
+ {
+ element_count = MIN(element_count, p_queue->size);
+ }
+ else
+ {
+ size_t available = nrf_queue_available_get(p_queue);
+ element_count = MIN(element_count, available);
+ }
+
+ queue_write(p_queue, p_data, element_count);
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Put in %d elements (start address: 0x%08X), requested :%d",
+ element_count, p_data, req_element_count);
+
+ return element_count;
+}
+
+/**@brief Read elements from the queue. This function assumes that there are enough elements
+ * in the queue to read and that this process will not be interrupted.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_data Pointer to the buffer where elements will be copied.
+ * @param[in] element_count Number of elements to read.
+ */
+static void queue_read(nrf_queue_t const * p_queue, void * p_data, uint32_t element_count)
+{
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+ size_t continuous = (front <= back) ? (back - front) : (p_queue->size + 1 - front);
+ void const * p_read_ptr = (void const *)((size_t)p_queue->p_buffer
+ + front * p_queue->element_size);
+
+ if (element_count <= continuous)
+ {
+ memcpy(p_data,
+ p_read_ptr,
+ element_count * p_queue->element_size);
+
+ p_queue->p_cb->front = ((front + element_count) <= p_queue->size)
+ ? (front + element_count)
+ : 0;
+ }
+ else
+ {
+ size_t first_read_length = continuous * p_queue->element_size;
+ memcpy(p_data,
+ p_read_ptr,
+ first_read_length);
+
+ size_t elements_left = element_count - continuous;
+ memcpy((void *)((size_t)p_data + first_read_length),
+ p_queue->p_buffer,
+ elements_left * p_queue->element_size);
+
+ p_queue->p_cb->front = elements_left;
+ }
+}
+
+ret_code_t nrf_queue_read(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+
+ if (element_count == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if (element_count <= queue_utilization_get(p_queue))
+ {
+ queue_read(p_queue, p_data, element_count);
+ }
+ else
+ {
+ status = NRF_ERROR_NOT_FOUND;
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Read %d elements (start address: 0x%08X), status :%d",
+ element_count, p_data, status);
+ return status;
+}
+
+size_t nrf_queue_out(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count)
+{
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+
+ size_t req_element_count = element_count;
+
+ if (element_count == 0)
+ {
+ return 0;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ size_t utilization = queue_utilization_get(p_queue);
+ element_count = MIN(element_count, utilization);
+
+ queue_read(p_queue, p_data, element_count);
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Out %d elements (start address: 0x%08X), requested :%d",
+ element_count, p_data, req_element_count);
+ return element_count;
+}
+
+void nrf_queue_reset(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+
+ CRITICAL_REGION_ENTER();
+
+ memset(p_queue->p_cb, 0, sizeof(nrf_queue_cb_t));
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Reset");
+}
+
+size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue)
+{
+ size_t utilization;
+ ASSERT(p_queue != NULL);
+
+ CRITICAL_REGION_ENTER();
+
+ utilization = queue_utilization_get(p_queue);
+
+ CRITICAL_REGION_EXIT();
+
+ return utilization;
+}
+
+bool nrf_queue_is_empty(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+ return (front == back);
+}
+
+size_t nrf_queue_available_get(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ return p_queue->size - nrf_queue_utilization_get(p_queue);
+}
+
+size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ return p_queue->p_cb->max_utilization;
+}
+
+void nrf_queue_max_utilization_reset(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ p_queue->p_cb->max_utilization = 0;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_QUEUE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h
new file mode 100644
index 0000000..1ba2a92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h
@@ -0,0 +1,429 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**
+* @defgroup nrf_queue Queue module
+* @{
+* @ingroup app_common
+* @brief Functions that handle the queue instances.
+*/
+
+#ifndef NRF_QUEUE_H__
+#define NRF_QUEUE_H__
+
+#include <stdint.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_assert.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "nrf_log_instance.h"
+#include "nrf_section.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define NRF_QUEUE_LOG_NAME queue
+
+/**@brief Queue control block. */
+typedef struct
+{
+ volatile size_t front; //!< Queue front index.
+ volatile size_t back; //!< Queue back index.
+ size_t max_utilization; //!< Maximum utilization of the queue.
+} nrf_queue_cb_t;
+
+/**@brief Supported queue modes. */
+typedef enum
+{
+ NRF_QUEUE_MODE_OVERFLOW, //!< If the queue is full, new element will overwrite the oldest.
+ NRF_QUEUE_MODE_NO_OVERFLOW, //!< If the queue is full, new element will not be accepted.
+} nrf_queue_mode_t;
+
+/**@brief Instance of the queue. */
+typedef struct
+{
+ nrf_queue_cb_t * p_cb; //!< Pointer to the instance control block.
+ void * p_buffer; //!< Pointer to the memory that is used as storage.
+ size_t size; //!< Size of the queue.
+ size_t element_size; //!< Size of one element.
+ nrf_queue_mode_t mode; //!< Mode of the queue.
+#if NRF_QUEUE_CLI_CMDS
+ const char * p_name; //!< Pointer to string with queue name.
+#endif
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
+} nrf_queue_t;
+
+#if NRF_QUEUE_CLI_CMDS
+#define __NRF_QUEUE_ASSIGN_POOL_NAME(_name) .p_name = STRINGIFY(_name),
+#else
+#define __NRF_QUEUE_ASSIGN_POOL_NAME(_name)
+#endif
+/**@brief Create a queue instance.
+ *
+ * @note This macro reserves memory for the given queue instance.
+ *
+ * @param[in] _type Type which is stored.
+ * @param[in] _name Name of the queue.
+ * @param[in] _size Size of the queue.
+ * @param[in] _mode Mode of the queue.
+ */
+#define NRF_QUEUE_DEF(_type, _name, _size, _mode) \
+ static _type CONCAT_2(_name, _nrf_queue_buffer[(_size) + 1]); \
+ static nrf_queue_cb_t CONCAT_2(_name, _nrf_queue_cb); \
+ NRF_LOG_INSTANCE_REGISTER(NRF_QUEUE_LOG_NAME, _name, \
+ NRF_QUEUE_CONFIG_INFO_COLOR, \
+ NRF_QUEUE_CONFIG_DEBUG_COLOR, \
+ NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL, \
+ NRF_QUEUE_CONFIG_LOG_ENABLED ? \
+ NRF_QUEUE_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ NRF_SECTION_ITEM_REGISTER(nrf_queue, const nrf_queue_t _name) = \
+ { \
+ .p_cb = &CONCAT_2(_name, _nrf_queue_cb), \
+ .p_buffer = CONCAT_2(_name,_nrf_queue_buffer), \
+ .size = (_size), \
+ .element_size = sizeof(_type), \
+ .mode = _mode, \
+ __NRF_QUEUE_ASSIGN_POOL_NAME(_name) \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_QUEUE_LOG_NAME, _name) \
+ }
+
+/**@brief Declare a queue interface.
+ *
+ * @param[in] _type Type which is stored.
+ * @param[in] _name Name of the queue.
+ */
+#define NRF_QUEUE_INTERFACE_DEC(_type, _name) \
+ ret_code_t _name##_push(_type const * p_element); \
+ ret_code_t _name##_pop(_type * p_element); \
+ ret_code_t _name##_peek(_type * p_element); \
+ ret_code_t _name##_write(_type const * p_data, \
+ size_t element_count); \
+ ret_code_t _name##_read(_type * p_data, \
+ size_t element_count); \
+ size_t _name##_out(_type * p_data, \
+ size_t element_count); \
+ size_t _name##_in(_type const * p_data, \
+ size_t element_count); \
+ bool _name##_is_full(void); \
+ bool _name##_is_empty(void); \
+ size_t _name##_utilization_get(void); \
+ size_t _name##_available_get(void); \
+ size_t _name##_max_utilization_get(void); \
+ void _name##_reset(void)
+
+/**@brief Define a queue interface.
+ *
+ * @param[in] _type Type which is stored.
+ * @param[in] _name Name of the queue.
+ * @param[in] _p_queue Queue instance.
+ */
+#define NRF_QUEUE_INTERFACE_DEF(_type, _name, _p_queue) \
+ ret_code_t _name##_push(_type const * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_push((_p_queue), p_element); \
+ } \
+ ret_code_t _name##_pop(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_pop((_p_queue), p_element); \
+ } \
+ ret_code_t _name##_peek(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_peek((_p_queue), p_element); \
+ } \
+ ret_code_t _name##_write(_type const * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_write((_p_queue), p_data, element_count); \
+ } \
+ ret_code_t _name##_read(_type * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_read((_p_queue), p_data, element_count); \
+ } \
+ size_t _name##_in(_type const * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_in((_p_queue), p_data, element_count); \
+ } \
+ size_t _name##_out(_type * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_out((_p_queue), p_data, element_count); \
+ } \
+ bool _name##_is_full(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ return nrf_queue_is_full(_p_queue); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ } \
+ bool _name##_is_empty(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_is_empty(_p_queue); \
+ } \
+ size_t _name##_utilization_get(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_utilization_get(_p_queue); \
+ } \
+ size_t _name##_available_get(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_available_get(_p_queue); \
+ } \
+ size_t _name##_max_utilization_get(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_max_utilization_get(_p_queue); \
+ } \
+ void _name##_reset(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ nrf_queue_reset(_p_queue); \
+ }
+
+/**@brief Function for pushing an element to the end of queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_element Pointer to the element that will be stored in the queue.
+ *
+ * @return NRF_SUCCESS If an element has been successfully added.
+ * @return NRF_ERROR_NO_MEM If the queue is full (only in @ref NRF_QUEUE_MODE_NO_OVERFLOW).
+ */
+ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element);
+
+/**@brief Generic pop implementation.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_element Pointer where the element will be copied.
+ * @param[out] just_peek If true, the returned element will not be removed from queue.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue,
+ void * p_element,
+ bool just_peek);
+
+/**@brief Pop element from the front of the queue.
+ *
+ * @param[in] _p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] _p_element Pointer where the element will be copied.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+#define nrf_queue_pop(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), false)
+
+/**@brief Peek element from the front of the queue.
+ *
+ * @param[in] _p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] _p_element Pointer where the element will be copied.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+#define nrf_queue_peek(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), true)
+
+/**@brief Function for writing elements to the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_data Pointer to the buffer with elements to write.
+ * @param[in] element_count Number of elements to write.
+ *
+ * @return NRF_SUCCESS If an element was written.
+ * @return NRF_ERROR_NO_MEM There is not enough space in the queue. No element was written.
+ */
+ret_code_t nrf_queue_write(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count);
+
+/**@brief Function for writing a portion of elements to the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_data Pointer to the buffer with elements to write.
+ * @param[in] element_count Number of elements to write.
+ *
+ * @return The number of added elements.
+ */
+size_t nrf_queue_in(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count);
+
+/**@brief Function for reading elements from the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_data Pointer to the buffer where elements will be copied.
+ * @param[in] element_count Number of elements to read.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND There is not enough elements in the queue.
+ */
+ret_code_t nrf_queue_read(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count);
+
+/**@brief Function for reading a portion of elements from the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_data Pointer to the buffer where elements will be copied.
+ * @param[in] element_count Number of elements to read.
+ *
+ * @return The number of read elements.
+ */
+size_t nrf_queue_out(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count);
+
+/**@brief Function for checking if the queue is full.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return True if the queue is full.
+ */
+bool nrf_queue_is_full(nrf_queue_t const * p_queue);
+
+/**@brief Function for checking if the queue is empty.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return True if the queue is empty.
+ */
+bool nrf_queue_is_empty(nrf_queue_t const * p_queue);
+
+/**@brief Function for getting the current queue utilization.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Current queue utilization.
+ */
+size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue);
+
+/**@brief Function for getting the size of available space.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Size of available space.
+ */
+size_t nrf_queue_available_get(nrf_queue_t const * p_queue);
+
+/**@brief Function for getting the maximal queue utilization.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Maximal queue utilization.
+ */
+size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue);
+
+/**@brief Function for resetting the maximal queue utilization.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ */
+void nrf_queue_max_utilization_reset(nrf_queue_t const * p_queue);
+
+/**@brief Function for resetting the queue state.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ */
+void nrf_queue_reset(nrf_queue_t const * p_queue);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_QUEUE_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c
new file mode 100644
index 0000000..d5357ca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c
@@ -0,0 +1,288 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_SCHEDULER)
+#include "app_scheduler.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_soc.h"
+#include "nrf_assert.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. */
+
+#if APP_SCHEDULER_WITH_PROFILER
+static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */
+#endif
+
+#if APP_SCHEDULER_WITH_PAUSE
+static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing
+ and resuming the scheduler. */
+#endif
+
+/**@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;
+
+#if APP_SCHEDULER_WITH_PROFILER
+ m_max_queue_utilization = 0;
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+uint16_t app_sched_queue_space_get()
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t free_space = m_queue_size - ((end >= start) ?
+ (end - start) : (m_queue_size + 1 - start + end));
+ return free_space;
+}
+
+
+#if APP_SCHEDULER_WITH_PROFILER
+static void queue_utilization_check(void)
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t queue_utilization = (end >= start) ? (end - start) :
+ (m_queue_size + 1 - start + end);
+
+ if (queue_utilization > m_max_queue_utilization)
+ {
+ m_max_queue_utilization = queue_utilization;
+ }
+}
+
+uint16_t app_sched_queue_utilization_get(void)
+{
+ return m_max_queue_utilization;
+}
+#endif // APP_SCHEDULER_WITH_PROFILER
+
+
+uint32_t app_sched_event_put(void const * 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);
+
+ #if APP_SCHEDULER_WITH_PROFILER
+ // This function call must be protected with critical region because
+ // it modifies 'm_max_queue_utilization'.
+ queue_utilization_check();
+ #endif
+ }
+
+ 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;
+}
+
+
+#if APP_SCHEDULER_WITH_PAUSE
+void app_sched_pause(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter < UINT32_MAX)
+ {
+ m_scheduler_paused_counter++;
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+void app_sched_resume(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter > 0)
+ {
+ m_scheduler_paused_counter--;
+ }
+ CRITICAL_REGION_EXIT();
+}
+#endif //APP_SCHEDULER_WITH_PAUSE
+
+
+/**@brief Function for checking if scheduler is paused which means that should break processing
+ * events.
+ *
+ * @return Boolean value - true if scheduler is paused, false otherwise.
+ */
+static __INLINE bool is_app_sched_paused(void)
+{
+#if APP_SCHEDULER_WITH_PAUSE
+ return (m_scheduler_paused_counter > 0);
+#else
+ return false;
+#endif
+}
+
+
+void app_sched_execute(void)
+{
+ while (!is_app_sched_paused() && !APP_SCHED_QUEUE_EMPTY())
+ {
+ // Since this function is only called from the main loop, there is no
+ // need for a critical region here, however a special care must be taken
+ // regarding update of the queue start index (see the end of the loop).
+ uint16_t event_index = m_queue_start_index;
+
+ void * p_event_data;
+ uint16_t event_data_size;
+ app_sched_event_handler_t event_handler;
+
+ p_event_data = &m_queue_event_data[event_index * m_queue_event_size];
+ event_data_size = m_queue_event_headers[event_index].event_data_size;
+ event_handler = m_queue_event_headers[event_index].handler;
+
+ event_handler(p_event_data, event_data_size);
+
+ // Event processed, now it is safe to move the queue start index,
+ // so the queue entry occupied by this event can be used to store
+ // a next one.
+ m_queue_start_index = next_index(m_queue_start_index);
+ }
+}
+#endif //NRF_MODULE_ENABLED(APP_SCHEDULER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h
new file mode 100644
index 0000000..f55f389
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup 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.svg The high level design of the scheduler
+ */
+
+#ifndef APP_SCHEDULER_H__
+#define APP_SCHEDULER_H__
+
+#include "sdk_config.h"
+#include <stdint.h>
+#include "app_error.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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 const * p_event_data,
+ uint16_t event_size,
+ app_sched_event_handler_t handler);
+
+/**@brief Function for getting the maximum observed queue utilization.
+ *
+ * Function for tuning the module and determining QUEUE_SIZE value and thus module RAM usage.
+ *
+ * @note @ref APP_SCHEDULER_WITH_PROFILER must be enabled to use this functionality.
+ *
+ * @return Maximum number of events in queue observed so far.
+ */
+uint16_t app_sched_queue_utilization_get(void);
+
+/**@brief Function for getting the current amount of free space in the queue.
+ *
+ * @details The real amount of free space may be less if entries are being added from an interrupt.
+ * To get the sxact value, this function should be called from the critical section.
+ *
+ * @return Amount of free space in the queue.
+ */
+uint16_t app_sched_queue_space_get(void);
+
+/**@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.
+ *
+ * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
+ */
+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.
+ *
+ * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
+ */
+void app_sched_resume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_SCHEDULER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c
new file mode 100644
index 0000000..a4a5bf6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c
@@ -0,0 +1,298 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "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. */
+
+#if APP_SCHEDULER_WITH_PROFILER
+static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */
+#endif
+
+static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing
+ and resuming the scheduler. */
+
+/**@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(void)
+{
+ 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(void)
+{
+ 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;
+
+#if APP_SCHEDULER_WITH_PROFILER
+ m_max_queue_utilization = 0;
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+uint16_t app_sched_queue_space_get()
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t free_space = m_queue_size - ((end >= start) ?
+ (end - start) : (m_queue_size + 1 - start + end));
+ return free_space;
+}
+
+
+#if APP_SCHEDULER_WITH_PROFILER
+static __INLINE void check_queue_utilization(void)
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t queue_utilization = (end >= start) ? (end - start) :
+ (m_queue_size + 1 - start + end);
+
+ if (queue_utilization > m_max_queue_utilization)
+ {
+ m_max_queue_utilization = queue_utilization;
+ }
+}
+
+uint16_t app_sched_queue_utilization_get(void)
+{
+ return m_max_queue_utilization;
+}
+#endif // APP_SCHEDULER_WITH_PROFILER
+
+
+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;
+ }
+
+ #if APP_SCHEDULER_WITH_PROFILER
+ check_queue_utilization();
+ #endif
+
+ 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_pause(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter < UINT32_MAX)
+ {
+ m_scheduler_paused_counter++;
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+
+void app_sched_resume(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter > 0)
+ {
+ m_scheduler_paused_counter--;
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+/**@brief Function for checking if scheduler is paused which means that should break processing
+ * events.
+ *
+ * @return Boolean value - true if scheduler is paused, false otherwise.
+ */
+static __INLINE bool is_app_sched_paused(void)
+{
+ return (m_scheduler_paused_counter > 0);
+}
+
+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 ((!is_app_sched_paused()) &&
+ (app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS))
+ {
+ event_handler(p_event_data, event_data_size);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c
new file mode 100644
index 0000000..763bf60
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c
@@ -0,0 +1,1179 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#if APP_SDCARD_ENABLED
+
+#include "app_sdcard.h"
+#include "nrf_gpio.h"
+#include "nrf_drv_spi.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+
+#include "nrf_pt.h"
+
+#define CMD_MASK 0x40
+#define ACMD_MASK 0x80
+#define CMD0 (CMD_MASK | 0) /**< SDC/MMC command 0: GO_IDLE_STATE. */
+#define CMD1 (CMD_MASK | 1) /**< SDC/MMC command 1: SEND_OP_COND (MMC). */
+#define CMD8 (CMD_MASK | 8) /**< SDC/MMC command 8: SEND_IF_COND. */
+#define CMD9 (CMD_MASK | 9) /**< SDC/MMC command 9: SEND_CSD. */
+#define CMD10 (CMD_MASK | 10) /**< SDC/MMC command 10: SEND_CID. */
+#define CMD12 (CMD_MASK | 12) /**< SDC/MMC command 12: STOP_TRANSMISSION. */
+#define CMD16 (CMD_MASK | 16) /**< SDC/MMC command 16: SET_BLOCKLEN. */
+#define CMD17 (CMD_MASK | 17) /**< SDC/MMC command 17: READ_SINGLE_BLOCK. */
+#define CMD18 (CMD_MASK | 18) /**< SDC/MMC command 18: READ_MULTIPLE_BLOCK. */
+#define CMD23 (CMD_MASK | 23) /**< SDC/MMC command 23: SET_BLOCK_COUNT (MMC). */
+#define CMD24 (CMD_MASK | 24) /**< SDC/MMC command 24: WRITE_BLOCK. */
+#define CMD25 (CMD_MASK | 25) /**< SDC/MMC command 25: WRITE_MULTIPLE_BLOCK. */
+#define CMD32 (CMD_MASK | 32) /**< SDC/MMC command 32: ERASE_ER_BLK_START. */
+#define CMD33 (CMD_MASK | 33) /**< SDC/MMC command 33: ERASE_ER_BLK_END. */
+#define CMD38 (CMD_MASK | 38) /**< SDC/MMC command 38: ERASE. */
+#define CMD55 (CMD_MASK | 55) /**< SDC/MMC command 55: APP_CMD. */
+#define CMD58 (CMD_MASK | 58) /**< SDC/MMC command 58: READ_OCR. */
+#define ACMD13 (ACMD_MASK | CMD_MASK | 13) /**< SDC application command 13: SD_STATUS. */
+#define ACMD23 (ACMD_MASK | CMD_MASK | 23) /**< SDC application command 23: SET_WR_BLK_ERASE_COUNT. */
+#define ACMD41 (ACMD_MASK | CMD_MASK | 41) /**< SDC application command 41: SEND_OP_COND. */
+
+#define IS_ACMD(CMD) ((CMD) & ACMD_MASK) /**< Check if command is an application command (ACMD). */
+
+#define SDC_COMMAND_LEN 6 /**< Length of a command structure sent to the card. */
+#define SDC_COMMAND_POS 0 /**< Position of a command field inside the command structure. */
+#define SDC_COMMAND_MASK 0x7F /**< Bit mask of a command field. */
+#define SDC_COMMAND_ARG_POS 1 /**< Position of a 32-bit argument inside the command structure. */
+#define SDC_COMMAND_CRC_POS 5 /**< Position of a CRC field inside the command structure. */
+
+#define SDC_MAX_NCR 8 /**< Maximum number of "busy" bytes sent before command response. */
+#define SDC_R1_LEN 1 /**< Length of R1 format response. */
+#define SDC_R3_LEN 5 /**< Length of R3 format response. */
+#define SDC_R7_LEN 5 /**< Length of R7 format response. */
+#define SDC_R_MAX_LEN 5 /**< Maximum length of command response. */
+
+#define SDC_FLAG_IN_IDLE_STATE 0x01 /**< R1 response flag bit mask: idle state. */
+#define SDC_FLAG_ERASE_RESET 0x02 /**< R1 response flag bit mask: erase reset. */
+#define SDC_FLAG_ILLEGAL_COMMAND 0x04 /**< R1 response flag bit mask: illegal command. */
+#define SDC_FLAG_COM_CRC_ERROR 0x08 /**< R1 response flag bit mask: CRC error. */
+#define SDC_FLAG_ERASE_SEQUENCE_ERROR 0x10 /**< R1 response flag bit mask: erase sequence error. */
+#define SDC_FLAG_ADDRESS_ERROR 0x20 /**< R1 response flag bit mask: address error. */
+#define SDC_FLAG_PARAMETER_ERROR 0x40 /**< R1 response flag bit mask: parameter error. */
+
+#define SDC_HCS_FLAG_MASK (1uL << 30) /**< High capacity support bit mask. */
+
+#define SDC_EMPTY_BYTE 0xFF /**< Idle state token. */
+#define SDC_BUSY_BYTE 0x00 /**< Busy byte token. */
+#define SDC_TOKEN_START_BLOCK 0xFE /**< Data block start token. */
+#define SDC_TOKEN_START_BLOCK_MULT 0xFC /**< Data block start token for multiple write operation. */
+#define SDC_TOKEN_DATA_RESP_MASK 0x1F /**< Data response token mask. */
+#define SDC_TOKEN_DATA_RESP_ACCEPTED 0x05 /**< Data response message: accepted. */
+#define SDC_TOKEN_DATA_RESP_CRC_ERR 0x0B /**< Data response message: CRC error. */
+#define SDC_TOKEN_DATA_RESP_DATA_ERR 0x0D /**< Data response message: data error. */
+#define SDC_TOKEN_STOP_TRAN 0xFD /**< Stop transmission token. */
+
+#define SDC_MAX_RETRY_COUNT_INIT 2000 /**< Maximum number of retries while card is busy (identification stage). */
+#define SDC_MAX_RETRY_COUNT 20000 /**< Maximum number of retries while card is busy. */
+#define SDC_SPI_MTU 240 /**< Maximum number of bytes in one SPI transaction. */
+#define SDC_CRC_CMD0 0x95 /**< Fixed CRC for reset command. */
+#define SDC_CRC_CMD8 0x87 /**< Fixed CRC for CMD8. */
+#define SDC_CRC_DUMMY 0xFF /**< Dummy CRC value. */
+
+#define SDC_CMD_BUF_LEN 16 /**< Size of a buffer for storing SDC commands. */
+#define SDC_WORK_BUF_LEN 16 /**< Size of a working buffer. */
+#define SDC_DATA_WAIT_TX_SIZE 16 /**< Number of bytes sent during data / busy wait. */
+
+#define SDC_CS_ASSERT() do { nrf_gpio_pin_clear(m_cb.cs_pin); } while (0) /**< Set CS pin to active state. */
+#define SDC_CS_DEASSERT() do { nrf_gpio_pin_set(m_cb.cs_pin); } while (0) /**< Set CS pin to inactive state. */
+
+#define SDC_PT &m_cb.state.pt /**< Macro for getting SDC task structure pointer (Protothread). */
+#define SDC_PT_SUB &m_cb.state.pt_sub /**< Macro for getting SDC sub-task structure pointer (Protothread). */
+
+/** Break current task (Protothread). */
+#define SDC_BREAK(PT, EXIT_CODE) do { \
+ *p_exit_code = (EXIT_CODE); \
+ PT_EXIT(PT); \
+ } while (0)
+
+/**< Check the value of R1 response and break current task on error. */
+#define SDC_RESP_CHECK(PT, R1) do { \
+ if ((R1) & ~(SDC_FLAG_IN_IDLE_STATE | SDC_FLAG_ERASE_RESET)) \
+ { \
+ SDC_BREAK((PT), SDC_ERROR_COMMUNICATION); \
+ } \
+ } while (0)
+
+/**< Check the result of an SDC operation and break on failure. */
+#define SDC_RESULT_CHECK(PT, RESULT) do { \
+ if ((RESULT) != SDC_SUCCESS) \
+ { \
+ SDC_BREAK((PT), RESULT); \
+ } \
+ } while (0);
+
+
+static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(APP_SDCARD_SPI_INSTANCE); /**< SPI instance. */
+
+/**
+ * @brief SDC response type.
+ */
+typedef enum {
+ SDC_RNONE = 0,
+ SDC_R1,
+ SDC_R3,
+ SDC_R7
+} sdc_response_t;
+
+/**
+ * @brief SDC operation state.
+ */
+typedef enum {
+ SDC_UNINITIALIZED = 0, ///< Card not initialized.
+ SDC_OP_RESET = 1, ///< Reset state.
+ SDC_OP_IDENTIFICATION = 2, ///< Identification procedure.
+ SDC_OP_IDLE = 3, ///< Idle state.
+ SDC_OP_READ = 4, ///< Data read procedure.
+ SDC_OP_WRITE = 5 ///< Data write procedure.
+} sdc_op_t;
+
+/**
+ * @brief SDC data bus state.
+ */
+typedef enum {
+ SDC_BUS_IDLE = 0, ///< Idle state, no active transfer.
+ SDC_BUS_CMD = 1, ///< Command is being transfered.
+ SDC_BUS_ACMD = 2, ///< Application command header transfer.
+ SDC_BUS_DATA_WAIT = 3, ///< Data wait state.
+ SDC_BUS_DATA = 4 ///< Data block transfer in progress.
+} sdc_bus_state_t;
+
+/**
+ * @brief Current read/write operation state structure.
+ */
+typedef struct {
+ uint8_t * buffer; ///< Local data buffer.
+ uint32_t address; ///< Data block address.
+ uint16_t block_count; ///< Total number of blocks in read/write operation.
+ uint16_t blocks_left; ///< Blocks left in current read/write operation.
+ uint16_t position; ///< Number of blocks left to read/write.
+} sdc_rw_op_t;
+
+/**
+ * @brief SDC state structure.
+ */
+typedef struct {
+ sdc_rw_op_t rw_op; ///< Read/write operation state.
+ pt_t pt; ///< Current task (Protothread) state.
+ pt_t pt_sub; ///< Current sub-task (Protothread) state.
+ uint16_t retry_count; ///< Number of retries left.
+ volatile sdc_op_t op; ///< Current operation.
+ sdc_bus_state_t bus_state; ///< Current data bud state.
+ uint8_t rsp_len; ///< Expected response length.
+} sdc_state_t;
+
+/**
+ * @beirf SDC control block.
+ */
+typedef struct {
+ sdc_event_handler_t handler; ///< Event handler.
+ app_sdc_info_t info; ///< Card information structure.
+ sdc_state_t state; ///< Card state structure
+ uint8_t cmd_buf[SDC_CMD_BUF_LEN]; ///< Command buffer.
+ uint8_t rsp_buf[SDC_CMD_BUF_LEN]; ///< Card response buffer.
+ uint8_t work_buf[SDC_WORK_BUF_LEN]; ///< Working buffer
+ uint8_t cs_pin; ///< Chip select pin number.
+} sdc_cb_t;
+
+static sdc_cb_t m_cb; ///< SDC control block.
+
+
+/**
+ * @brief Function for requesting the SPI transaction.
+ *
+ * The SPI bus must be initialized prior to use of this function.
+ *
+ * @param[in] p_txb Pointer to the TX buffer.
+ * @param[in] tx_len TX buffer length.
+ * @param[out] p_rxb Pointer to the RX buffer.
+ * @param[in] tx_len RX buffer length.
+ */
+__STATIC_INLINE void sdc_spi_transfer(uint8_t const * const p_txb,
+ uint8_t tx_len,
+ uint8_t * const p_rxb,
+ uint8_t rx_len)
+{
+ SDC_CS_ASSERT();
+ ret_code_t err_code = nrf_drv_spi_transfer(&m_spi, p_txb, tx_len, p_rxb, rx_len);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**
+ * @brief Function for switching the SPI clock to high speed mode.
+ */
+__STATIC_INLINE void sdc_spi_hispeed(void)
+{
+#ifdef SPI_PRESENT
+ nrf_spi_frequency_set(m_spi.u.spi.p_reg,
+ (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA);
+#else
+ nrf_spim_frequency_set(m_spi.u.spim.p_reg,
+ (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA);
+#endif
+}
+
+
+/**
+ * @brief Function for extracting the number of data block from the CSD structure.
+ *
+ * @param[in] p_csd Pointer to the card CSD structure.
+ *
+ * @return Number of data blocks or 0 if unsupported / invalid structure was provided.
+ */
+static uint32_t sdc_calculate_size(uint8_t const * const p_csd)
+{
+ // Values are calculated as stated in SD Specifications, chapter 5.3.
+ uint8_t csd_version = p_csd[0] >> 6;
+
+ switch (csd_version)
+ {
+ case 0:
+ case 2:
+ {
+ // SD Standard Capacity or MMC.
+ uint32_t c_size = ((uint32_t) p_csd[8] >> 6) + (((uint32_t) p_csd[7]) << 2)
+ + ((uint32_t)(p_csd[6] & 0x03) << 10);
+ uint32_t read_bl_len = p_csd[5] & 0x0F;
+ uint32_t c_size_mult = ((p_csd[10] & 0x80) >> 7) + ((p_csd[9] & 0x03) << 1);
+
+ // Block size in this implementation is set to 512, so the resulting number of bytes
+ // is divided by 512 (2^9)
+ return (c_size + 1) << (read_bl_len + c_size_mult + 2 - 9);
+ }
+ case 1:
+ {
+ // SD High Capacity.
+ uint32_t c_size = (uint32_t) p_csd[9] + ((uint32_t) p_csd[8] << 8)
+ + (((uint32_t) p_csd[7] & 0x3F) << 16);
+
+ // According to SD 2.0 Specifications, capacity = (C_SIZE + 1) * 512KByte.
+ // Block size is equal to 512, so the result is divided by 512.
+ return (c_size + 1) * 1024uL;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Non-blocking function for sending a command to the card.
+ *
+ * @param[in] cmd SDC command ID.
+ * @param[in] arg 32-bit command argument.
+ * @param[in] rsp_type Expected command response format.
+ *
+ * @retval NRF_SUCCESS If command transmission was started successfully.
+ * @retval NRF_ERROR_BUSY If the card is not in idle state.
+ */
+static ret_code_t sdc_cmd(uint8_t cmd, uint32_t arg, sdc_response_t rsp_type)
+{
+ if (m_cb.state.bus_state != SDC_BUS_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint8_t offset = 0;
+
+ m_cb.state.bus_state = SDC_BUS_CMD;
+ if (IS_ACMD(cmd))
+ {
+ // ACMD is a combination of CMD55 and the requested command,
+ // which will be placed next in the command buffer.
+ offset = SDC_COMMAND_LEN;
+ m_cb.state.bus_state = SDC_BUS_ACMD;
+ m_cb.cmd_buf[SDC_COMMAND_POS] = CMD55;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_CRC_POS] = SDC_CRC_DUMMY;
+ }
+
+ m_cb.cmd_buf[SDC_COMMAND_POS + offset] = cmd & SDC_COMMAND_MASK;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + offset] = (uint8_t)(arg >> 24);
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1 + offset] = (uint8_t)(arg >> 16);
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2 + offset] = (uint8_t)(arg >> 8);
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3 + offset] = (uint8_t)(arg);
+
+ // Use predefined CRC values and omit the crc calculation if not required.
+ uint8_t crc;
+ switch (cmd)
+ {
+ case CMD0:
+ crc = SDC_CRC_CMD0;
+ break;
+ case CMD8:
+ crc = SDC_CRC_CMD8;
+ break;
+ default:
+ crc = SDC_CRC_DUMMY;
+ break;
+ }
+ m_cb.cmd_buf[SDC_COMMAND_CRC_POS + offset] = crc;
+
+ switch (rsp_type)
+ {
+ case SDC_R3:
+ m_cb.state.rsp_len = SDC_R3_LEN;
+ break;
+ case SDC_R7:
+ m_cb.state.rsp_len = SDC_R7_LEN;
+ break;
+ default:
+ m_cb.state.rsp_len = SDC_R1_LEN;
+ break;
+ }
+
+ uint8_t response_len = (IS_ACMD(cmd)) ? SDC_R1_LEN : m_cb.state.rsp_len;
+ sdc_spi_transfer(m_cb.cmd_buf,
+ SDC_COMMAND_LEN,
+ m_cb.rsp_buf,
+ SDC_COMMAND_LEN + SDC_MAX_NCR + response_len);
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Data block read subroutine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transation.
+ * @param[in] rx_length Received data length.
+ * @param[in] block_len Size of a data block to read.
+ * @param[out] p_exit_code Pointer to the subroutine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_sub_data_read(uint8_t * p_rx_data,
+ uint8_t rx_length,
+ uint16_t block_len,
+ sdc_result_t * p_exit_code))
+{
+ PT_BEGIN(SDC_PT_SUB);
+ while (1)
+ {
+ ASSERT(block_len);
+ ASSERT(m_cb.state.rw_op.block_count);
+
+ m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count;
+
+ while (m_cb.state.rw_op.blocks_left)
+ {
+ m_cb.state.retry_count = 0;
+ m_cb.cmd_buf[0] = 0xFF;
+ m_cb.state.rw_op.position = 0;
+ m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
+
+ while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
+ {
+ SDC_BREAK(SDC_PT_SUB, SDC_ERROR_TIMEOUT);
+ }
+
+ // Search for the first token.
+ while (rx_length && p_rx_data[0] == SDC_EMPTY_BYTE)
+ {
+ ++p_rx_data;
+ --rx_length;
+ }
+
+ if (rx_length)
+ {
+ // A token has been found.
+ if (p_rx_data[0] == SDC_TOKEN_START_BLOCK)
+ {
+ // Expected data start token found.
+ // Copy the data bytes left in rx buffer into user buffer.
+ ++p_rx_data;
+ --rx_length;
+ m_cb.state.bus_state = SDC_BUS_DATA;
+ uint16_t copy_len = (rx_length > block_len) ? block_len : rx_length;
+ for (uint32_t i = 0; i < copy_len; ++i)
+ {
+ m_cb.state.rw_op.buffer[i] = p_rx_data[i];
+ }
+ m_cb.state.rw_op.position = copy_len;
+ m_cb.state.rw_op.buffer += copy_len;
+ }
+ else
+ {
+ // Data error.
+ SDC_BREAK(SDC_PT_SUB, SDC_ERROR_DATA);
+ }
+ }
+ else
+ {
+ // Continue transfer until token is received.
+ sdc_spi_transfer(m_cb.cmd_buf, 1, m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
+ PT_YIELD(SDC_PT_SUB);
+ }
+ }
+
+ while (m_cb.state.rw_op.position < block_len)
+ {
+ {
+ uint16_t chunk_size = block_len - m_cb.state.rw_op.position;
+ if (chunk_size > SDC_SPI_MTU)
+ {
+ chunk_size = SDC_SPI_MTU;
+ }
+
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.state.rw_op.buffer, chunk_size);
+ m_cb.state.rw_op.buffer += chunk_size;
+ m_cb.state.rw_op.position += chunk_size;
+ }
+ PT_YIELD(SDC_PT_SUB);
+ }
+
+ // Get the CRC.
+ --m_cb.state.rw_op.blocks_left;
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 2);
+ PT_YIELD(SDC_PT_SUB);
+
+
+
+ // Set rx length to 0 to force "busy check" transmission before next data block.
+ rx_length = 0;
+ }
+
+ // Send padding bytes.
+ m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 2);
+ PT_YIELD(SDC_PT_SUB);
+
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ SDC_BREAK(SDC_PT_SUB, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT_SUB)
+}
+
+
+/**
+ * @brief Card identification co-routine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transation.
+ * @param[in] rx_length Received data length.
+ * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_identification(uint8_t * p_rx_data,
+ uint8_t rx_length,
+ sdc_result_t * p_exit_code))
+{
+ uint8_t r1 = p_rx_data[0];
+ uint32_t rsp = ((uint32_t)p_rx_data[1] << 24)
+ | ((uint32_t)p_rx_data[2] << 16)
+ | ((uint32_t)p_rx_data[3] << 8)
+ | ((uint32_t)p_rx_data[4]);
+ uint32_t arg;
+ ret_code_t err_code;
+ sdc_result_t sub_exit_code;
+
+ PT_BEGIN(SDC_PT);
+ while (1)
+ {
+ err_code = sdc_cmd(CMD0, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ err_code = sdc_cmd(CMD0, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+
+ SDC_RESP_CHECK(SDC_PT, r1);
+ // Send CMD8 with fixed argument - 0x01AA.
+ err_code = sdc_cmd(CMD8, 0x1AA, SDC_R7);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+
+ if (!(r1 & SDC_FLAG_ILLEGAL_COMMAND))
+ {
+ // CMD8 was accepted - SD v2 card.
+ m_cb.info.type.version = SDC_TYPE_SDV2;
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ m_cb.state.retry_count = 0;
+ arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
+ err_code = sdc_cmd(ACMD41, arg, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+
+ if (r1 & SDC_FLAG_ILLEGAL_COMMAND)
+ {
+ // ACMD41 was rejected - MMC card.
+ m_cb.info.type.version = SDC_TYPE_MMCV3;
+ r1 &= ~SDC_FLAG_ILLEGAL_COMMAND;
+
+ do
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ err_code = sdc_cmd(CMD1, 0, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+ while (r1 & SDC_FLAG_IN_IDLE_STATE);
+ }
+ else
+ {
+ // SDv1 or SDv2 card. Send CMD58 or retry ACMD41 if not ready.
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ while (r1 & SDC_FLAG_IN_IDLE_STATE)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
+ err_code = sdc_cmd(ACMD41, arg, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ err_code = sdc_cmd(CMD58, 0, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ if (rsp & SDC_HCS_FLAG_MASK)
+ {
+ m_cb.info.type.sdhc = 1;
+ }
+ }
+
+ if (m_cb.info.type.version != SDC_TYPE_SDV2)
+ {
+ // Set block length to 512 (SDv1 and MMC cards only.)
+ err_code = sdc_cmd(CMD16, SDC_SECTOR_SIZE, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ // Setup the read operation and get the contents of 128-bit CSD register.
+ m_cb.state.rw_op.buffer = m_cb.work_buf;
+ m_cb.state.rw_op.block_count = 1;
+
+ err_code = sdc_cmd(CMD9, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ p_rx_data += SDC_R1_LEN;
+ rx_length -= SDC_R1_LEN;
+ PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, \
+ 16, &sub_exit_code));
+ SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
+
+ m_cb.info.num_blocks = sdc_calculate_size(m_cb.work_buf);
+ m_cb.info.block_len = SDC_SECTOR_SIZE;
+
+ SDC_BREAK(SDC_PT, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT)
+}
+
+
+/**
+ * @brief Data read co-routine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transaction.
+ * @param[in] rx_length Received data length.
+ * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_read(uint8_t * p_rx_data,
+ uint8_t rx_length,
+ sdc_result_t * p_exit_code))
+{
+ uint8_t r1;
+ ret_code_t err_code;
+ sdc_result_t sub_exit_code;
+
+ PT_BEGIN(SDC_PT);
+ while (1)
+ {
+ r1 = p_rx_data[0];
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ p_rx_data += SDC_R1_LEN;
+ rx_length -= SDC_R1_LEN;
+
+ // Run the block read subroutine.
+ PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length,
+ SDC_SECTOR_SIZE,
+ &sub_exit_code));
+ SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
+
+ if (m_cb.state.rw_op.block_count > 1)
+ {
+ // Send the STOP_TRANSMISSION command in multiple block read mode.
+ err_code = sdc_cmd(CMD12, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ }
+
+ SDC_BREAK(SDC_PT, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT)
+}
+
+
+/**
+ * @brief Data write co-routine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transation.
+ * @param[in] rx_length Received data length.
+ * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_write(uint8_t * rx_data,
+ uint8_t rx_length,
+ sdc_result_t * p_exit_code))
+{
+ ret_code_t err_code;
+ PT_BEGIN(SDC_PT);
+ while (1)
+ {
+ uint8_t r1;
+ r1 = rx_data[0];
+ SDC_RESP_CHECK(SDC_PT, r1);
+ if (m_cb.info.type.version != SDC_TYPE_MMCV3 && m_cb.state.rw_op.block_count > 1)
+ {
+ err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ r1 = rx_data[0];
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count;
+ while (m_cb.state.rw_op.blocks_left)
+ {
+ m_cb.state.rw_op.position = 0;
+ m_cb.state.bus_state = SDC_BUS_DATA;
+
+ // Send block start token.
+ m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
+ m_cb.cmd_buf[1] = (m_cb.state.rw_op.block_count > 1) ? SDC_TOKEN_START_BLOCK_MULT
+ : SDC_TOKEN_START_BLOCK;
+ sdc_spi_transfer(m_cb.cmd_buf, 2, m_cb.rsp_buf, 2);
+ PT_YIELD(SDC_PT);
+
+ // Send the data block.
+ while (m_cb.state.rw_op.position < SDC_SECTOR_SIZE)
+ {
+ {
+ uint16_t chunk_size = SDC_SECTOR_SIZE - m_cb.state.rw_op.position;
+ if (chunk_size > SDC_SPI_MTU)
+ {
+ chunk_size = SDC_SPI_MTU;
+ }
+ sdc_spi_transfer(&m_cb.state.rw_op.buffer[m_cb.state.rw_op.position],
+ chunk_size,
+ m_cb.rsp_buf,
+ 1);
+ m_cb.state.rw_op.position += chunk_size;
+ }
+ PT_YIELD(SDC_PT);
+ }
+ m_cb.state.rw_op.buffer += SDC_SECTOR_SIZE;
+
+ // Send the dummy CRC (2 bytes) and receive data response token (1 byte).
+ m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 3);
+ PT_YIELD(SDC_PT);
+
+ {
+ uint8_t token = m_cb.rsp_buf[2] & SDC_TOKEN_DATA_RESP_MASK;
+ if (token != SDC_TOKEN_DATA_RESP_ACCEPTED)
+ {
+ if (token == SDC_TOKEN_DATA_RESP_CRC_ERR
+ || token == SDC_TOKEN_DATA_RESP_DATA_ERR)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_DATA);
+ }
+ else
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_COMMUNICATION);
+ }
+ }
+ }
+
+ // Wait for the card to complete the write process.
+ m_cb.state.retry_count = 0;
+ while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
+ PT_YIELD(SDC_PT);
+
+ for (uint32_t i = 0; i < rx_length; ++i)
+ {
+ if (rx_data[i] != 0x00)
+ {
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ break;
+ }
+ }
+ }
+
+ --m_cb.state.rw_op.blocks_left;
+ }
+
+ if (m_cb.state.rw_op.block_count > 1)
+ {
+ // Send STOP_TRAN token + padding byte when writing multiple blocks.
+ m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
+ m_cb.cmd_buf[1] = SDC_TOKEN_STOP_TRAN;
+ sdc_spi_transfer(m_cb.cmd_buf, 2,
+ m_cb.rsp_buf, 3);
+ PT_YIELD(SDC_PT);
+
+ m_cb.state.retry_count = 0;
+ m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
+
+ // Wait for the card to complete the write process.
+ while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
+ PT_YIELD(SDC_PT);
+
+ for (uint32_t i = 0; i < rx_length; ++i)
+ {
+ if (rx_data[i] != 0x00)
+ {
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ break;
+ }
+ }
+ }
+ }
+
+ SDC_BREAK(SDC_PT, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT)
+}
+
+
+/**
+ * @brief SPI event handler.
+ *
+ * @param[in] p_event Pointer to the SPI event structure.
+ */
+static void spi_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context)
+{
+ uint8_t * rx_data = p_event->data.done.p_rx_buffer;
+ uint8_t rx_length = p_event->data.done.rx_length;
+
+ if (!m_cb.state.rw_op.blocks_left)
+ {
+ // Deassert CS pin if not in active data transfer.
+ SDC_CS_DEASSERT();
+ }
+
+ if (m_cb.state.bus_state == SDC_BUS_ACMD || m_cb.state.bus_state == SDC_BUS_CMD)
+ {
+ // Find the beginning of a response.
+ ASSERT(rx_length > SDC_COMMAND_LEN);
+ rx_length -= SDC_COMMAND_LEN;
+ rx_data += SDC_COMMAND_LEN;
+
+ if (p_event->data.done.p_tx_buffer[0] == CMD12)
+ {
+ // Ignore the first byte if CMD12 was sent.
+ if (rx_length)
+ {
+ --rx_length;
+ ++rx_data;
+ }
+ }
+
+ while (rx_length && rx_data[0] == SDC_EMPTY_BYTE)
+ {
+ --rx_length;
+ ++rx_data;
+ }
+ if (rx_length == 0)
+ {
+ if (p_event->data.done.p_tx_buffer[0] == CMD12)
+ {
+ // Ignore invalid reply on CMD12.
+ ++rx_length;
+ --rx_data;
+ }
+ else
+ {
+ rx_data = NULL;
+ }
+ }
+
+ if (!rx_data && m_cb.state.op != SDC_OP_RESET)
+ {
+ // Command response missing.
+ sdc_evt_t evt;
+ evt.result = SDC_ERROR_NOT_RESPONDING;
+ switch (m_cb.state.op)
+ {
+ case SDC_OP_RESET:
+ case SDC_OP_IDENTIFICATION:
+ evt.type = SDC_EVT_INIT;
+ m_cb.state.op = SDC_OP_IDLE;
+ APP_ERROR_CHECK(app_sdc_uninit());
+ break;
+ case SDC_OP_READ:
+ evt.type = SDC_EVT_READ;
+ break;
+ case SDC_OP_WRITE:
+ evt.type = SDC_EVT_WRITE;
+ break;
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ break;
+ }
+
+ SDC_CS_DEASSERT();
+ m_cb.state.op = SDC_OP_IDLE;
+ m_cb.handler(&evt);
+ return;
+ }
+
+ if (m_cb.state.bus_state == SDC_BUS_ACMD)
+ {
+ // Check the status of CMD55 and send the scheduled command if no errors has been reported.
+ m_cb.state.bus_state = SDC_BUS_CMD;
+ uint8_t r1 = rx_data[0];
+ if (!(r1 & (~SDC_FLAG_IN_IDLE_STATE)))
+ {
+ sdc_spi_transfer(m_cb.cmd_buf + SDC_COMMAND_LEN, SDC_COMMAND_LEN,
+ m_cb.rsp_buf, SDC_COMMAND_LEN + SDC_MAX_NCR + m_cb.state.rsp_len);
+ return;
+ }
+ }
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ }
+
+ sdc_result_t exit_code = SDC_ERROR_INTERNAL;
+ sdc_evt_t evt;
+ switch (m_cb.state.op)
+ {
+ case SDC_OP_RESET:
+ m_cb.state.op = SDC_OP_IDENTIFICATION;
+ PT_INIT(SDC_PT);
+ //lint -e{616}
+ case SDC_OP_IDENTIFICATION:
+ if (!PT_SCHEDULE(sdc_pt_identification(rx_data, rx_length, &exit_code)))
+ {
+ evt.type = SDC_EVT_INIT;
+ evt.result = exit_code;
+ m_cb.state.op = SDC_OP_IDLE;
+ SDC_CS_DEASSERT();
+ if (exit_code != SDC_SUCCESS)
+ {
+ // Initialization process failed. Roll back to uninitialized state.
+ APP_ERROR_CHECK(app_sdc_uninit());
+ }
+ sdc_spi_hispeed();
+ m_cb.handler(&evt);
+ }
+ break;
+ case SDC_OP_READ:
+ if (!PT_SCHEDULE(sdc_pt_read(rx_data, rx_length, &exit_code)))
+ {
+ evt.type = SDC_EVT_READ;
+ evt.result = exit_code;
+ m_cb.state.op = SDC_OP_IDLE;
+ m_cb.state.rw_op.block_count = 0;
+ m_cb.state.rw_op.blocks_left = 0;
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ SDC_CS_DEASSERT();
+ m_cb.handler(&evt);
+ }
+ break;
+ case SDC_OP_WRITE:
+ if (!PT_SCHEDULE(sdc_pt_write(rx_data, rx_length, &exit_code)))
+ {
+ evt.type = SDC_EVT_WRITE;
+ evt.result = exit_code;
+ m_cb.state.op = SDC_OP_IDLE;
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ m_cb.state.rw_op.block_count = 0;
+ m_cb.state.rw_op.blocks_left = 0;
+ SDC_CS_DEASSERT();
+ m_cb.handler(&evt);
+ }
+ break;
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ break;
+ }
+
+ return;
+}
+
+
+ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count)
+{
+ ASSERT(p_buf);
+
+ if (m_cb.state.op == SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_cb.state.op != SDC_OP_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ if (block_count == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_cb.state.op = SDC_OP_READ;
+
+ if (!m_cb.info.type.sdhc)
+ {
+ m_cb.state.rw_op.address = block_address * SDC_SECTOR_SIZE;
+ }
+ else
+ {
+ m_cb.state.rw_op.address = block_address;
+ }
+ m_cb.state.rw_op.buffer = p_buf;
+ m_cb.state.rw_op.block_count = block_count;
+ m_cb.state.rw_op.blocks_left = block_count;
+
+ PT_INIT(&m_cb.state.pt);
+ uint8_t command = (block_count > 1) ? CMD18 : CMD17;
+ ret_code_t err_code = sdc_cmd(command, m_cb.state.rw_op.address, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count)
+{
+ ASSERT(p_buf);
+
+ if (m_cb.state.op == SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_cb.state.op != SDC_OP_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ if (block_count == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ m_cb.state.op = SDC_OP_WRITE;
+
+ if (!m_cb.info.type.sdhc)
+ {
+ m_cb.state.rw_op.address = block_address * 512uL;
+ }
+ else
+ {
+ m_cb.state.rw_op.address = block_address;
+ }
+ m_cb.state.rw_op.buffer = (uint8_t *) p_buf;
+ m_cb.state.rw_op.block_count = block_count;
+ m_cb.state.rw_op.blocks_left = block_count;
+
+ PT_INIT(&m_cb.state.pt);
+
+ ret_code_t err_code;
+ if (block_count == 1)
+ {
+ err_code = sdc_cmd(CMD24, m_cb.state.rw_op.address, SDC_R1);
+
+ APP_ERROR_CHECK(err_code);
+ return NRF_SUCCESS;
+ }
+
+ if (m_cb.info.type.version == SDC_TYPE_MMCV3)
+ {
+ // Start multiple block write.
+ err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1);
+ }
+ else
+ {
+ // Set pre-erase for SD cards before sending CMD25.
+ err_code = sdc_cmd(ACMD23, block_count, SDC_R1);
+ }
+
+ APP_ERROR_CHECK(err_code);
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler)
+{
+ if (m_cb.state.op != SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if ((!event_handler)
+ || (p_config->cs_pin == NRF_DRV_SPI_PIN_NOT_USED)
+ || (p_config->miso_pin == NRF_DRV_SPI_PIN_NOT_USED)
+ || (p_config->mosi_pin == NRF_DRV_SPI_PIN_NOT_USED)
+ || (p_config->sck_pin == NRF_DRV_SPI_PIN_NOT_USED))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ ret_code_t err_code;
+ ASSERT(p_config->cs_pin && p_config->miso_pin
+ && p_config->mosi_pin && p_config->sck_pin);
+
+ // Configure chip select pin.
+ m_cb.cs_pin = p_config->cs_pin;
+ nrf_gpio_cfg_output(m_cb.cs_pin);
+ SDC_CS_DEASSERT();
+
+ const nrf_drv_spi_config_t spi_cfg = {
+ .sck_pin = p_config->sck_pin,
+ .mosi_pin = p_config->mosi_pin,
+ .miso_pin = p_config->miso_pin,
+ .ss_pin = NRF_DRV_SPI_PIN_NOT_USED,
+ .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY,
+ .orc = 0xFF,
+ .frequency = (nrf_drv_spi_frequency_t) APP_SDCARD_FREQ_INIT,
+ .mode = NRF_DRV_SPI_MODE_0,
+ .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,
+ };
+ err_code = nrf_drv_spi_init(&m_spi, &spi_cfg, spi_handler, NULL);
+ APP_ERROR_CHECK(err_code);
+
+ m_cb.handler = event_handler;
+ m_cb.state.op = SDC_OP_RESET;
+ m_cb.info.type.version = SDC_TYPE_UNKNOWN;
+ m_cb.info.type.sdhc = 0;
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+
+ // Send 80 clocks with CS inactive to switch into SPI mode.
+ m_cb.cmd_buf[0] = 0xFF;
+ err_code = nrf_drv_spi_transfer(&m_spi, m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 10);
+ APP_ERROR_CHECK(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_sdc_uninit(void)
+{
+ if (m_cb.state.op == SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_cb.state.op != SDC_OP_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_drv_spi_uninit(&m_spi);
+ nrf_gpio_cfg_input(m_cb.cs_pin, NRF_GPIO_PIN_NOPULL);
+
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ m_cb.state.op = SDC_UNINITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+bool app_sdc_busy_check(void)
+{
+ return ((m_cb.state.op != SDC_OP_IDLE) && (m_cb.state.op != SDC_UNINITIALIZED));
+}
+
+
+app_sdc_info_t const * app_sdc_info_get(void)
+{
+ if (m_cb.state.op >= SDC_OP_IDLE)
+ {
+ return &m_cb.info;
+ }
+ return NULL;
+}
+
+#endif //APP_SDCARD_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h
new file mode 100644
index 0000000..3621771
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup app_sdcard SD card library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Asynchronous Secure Digital card (SDC) and MultiMedia card (MMC) library.
+ */
+
+
+#ifndef APP_SDCARD_H_
+#define APP_SDCARD_H_
+
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#define SDC_SECTOR_SIZE 512 ///< Size of a single SD card block in bytes.
+
+#define APP_SDCARD_CONFIG(MOSI_PIN, MISO_PIN, SCK_PIN, CS_PIN) { \
+ .mosi_pin = MOSI_PIN, \
+ .miso_pin = MISO_PIN, \
+ .sck_pin = SCK_PIN, \
+ .cs_pin = CS_PIN \
+ }
+
+/**
+ * @brief SDC operation result.
+ */
+typedef enum {
+ SDC_SUCCESS = 0, ///< Operation successful.
+ SDC_ERROR_NOT_RESPONDING, ///< Card is not responding or not present.
+ SDC_ERROR_TIMEOUT, ///< Card response timeout.
+ SDC_ERROR_NOT_SUPPORTED, ///< Operation not supported.
+ SDC_ERROR_COMMUNICATION, ///< Communication error.
+ SDC_ERROR_DATA, ///< Data read/write error.
+ SDC_ERROR_INTERNAL, ///< Internal error.
+} sdc_result_t;
+
+/**
+ * @brief SDC event type.
+ */
+typedef enum {
+ SDC_EVT_INIT = 0, ///< Initialization procedure.
+ SDC_EVT_READ, ///< Data read procedure.
+ SDC_EVT_WRITE ///< Data write procedure.
+} sdc_evt_type_t;
+
+/**
+ * @brief SDC event structure.
+ */
+typedef struct {
+ sdc_evt_type_t type; ///< Event type.
+ sdc_result_t result; ///< Operation result.
+} sdc_evt_t;
+
+/**
+ * @brief SDC type and version.
+ */
+typedef enum {
+ SDC_TYPE_UNKNOWN = 0, ///< Unknown / uninitialized card.
+ SDC_TYPE_MMCV3, ///< MultiMedia card (MMC) version 3.
+ SDC_TYPE_SDV1, ///< Secure Digital card (SDC) version 1.0.
+ SDC_TYPE_SDV2 ///< Secure Digital card (SDC) version 2.0.
+} sdc_version_t;
+
+/**
+ * @brief SDC type information structure.
+ */
+typedef struct {
+ sdc_version_t version : 3; ///< Card type and version (SD or MMC).
+ uint8_t sdhc : 1; ///< Standard Capacity or High Capacity card.
+} sdc_type_t;
+
+/**
+ * @brief SDC configuration structure.
+ */
+typedef struct {
+ uint8_t mosi_pin; ///< Serial data in (MOSI / DI) pin number.
+ uint8_t miso_pin; ///< Serial data out (MISO / DO) pin number.
+ uint8_t sck_pin; ///< Serial clock (SCK) pin number.
+ uint8_t cs_pin; ///< Chip select (CS) pin number.
+} app_sdc_config_t;
+
+/**
+ * @brief SDC information structure.
+ */
+typedef struct {
+ uint32_t num_blocks; ///< Number of available data blocks.
+ uint16_t block_len; ///< Length (in bytes) of a single data block.
+ sdc_type_t type; ///< Card type information structure.
+} app_sdc_info_t;
+
+/**
+ * @brief SDC event handler type.
+ */
+typedef void (*sdc_event_handler_t)(sdc_evt_t const * p_event);
+
+
+/**
+ * @brief Function for initializing the card.
+ *
+ * @param[in] p_config Pointer to the SDC configuration structure.
+ * @param[in] event_handler Pointer to the event handler function.
+ *
+ * @retval NRF_SUCCESS If initialization process was started succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is already initialized or the initialization is in progress.
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified.
+ */
+ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler);
+
+
+/**
+ * @brief Function for uninitializing the card.
+ *
+ * @retval NRF_SUCCESS If card was uninitialized succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is not initialized.
+ * @retval NRF_ERROR_BUSY If there is an operation in progress.
+ */
+ret_code_t app_sdc_uninit(void);
+
+
+/**
+ * @brief Function for retrieving the card busy state.
+ *
+ * @retval true If there is an operation in progress.
+ * @retval false If the card is in idle state.
+ */
+bool app_sdc_busy_check(void);
+
+
+/**
+ * @brief Function for reading the data blocks from the card.
+ *
+ * @param[out] p_buf Pointer to the data buffer. Must not be null.
+ * @param[in] block_address Number of the first block to be read.
+ * @param[in] block_count Number of blocks to read. Must be greater than 0.
+ *
+ * @retval NRF_SUCCESS If block read operation was started succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is not initialized.
+ * @retval NRF_ERROR_BUSY If there is already an operation active.
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified.
+ */
+ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count);
+
+
+/**
+ * @brief Function for writing the data blocks to the card.
+ *
+ * @param[out] p_buf Pointer to the data to be written. Must not be null.
+ * @param[in] block_address Number of the first block to write.
+ * @param[in] block_count Number of blocks to write. Must be greater than 0.
+ *
+ * @retval NRF_SUCCESS If block write operation was started succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is not initialized.
+ * @retval NRF_ERROR_BUSY If there is already an operation active.
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified.
+ */
+ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count);
+
+
+/**
+ * @brief Function for retrieving the card information structure.
+ *
+ * @return Pointer to the card information structure or NULL if card is not initialized.
+ */
+app_sdc_info_t const * app_sdc_info_get(void);
+
+
+#endif //APP_SDC_H_
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c
new file mode 100644
index 0000000..c422a79
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sensorsim.h"
+
+
+void sensorsim_init(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_cfg->start_at_max)
+ {
+ p_state->current_val = p_cfg->max;
+ p_state->is_increasing = false;
+ }
+ else
+ {
+ p_state->current_val = p_cfg->min;
+ p_state->is_increasing = true;
+ }
+}
+
+
+uint32_t sensorsim_measure(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_state->is_increasing)
+ {
+ sensorsim_increment(p_state, p_cfg);
+ }
+ else
+ {
+ sensorsim_decrement(p_state, p_cfg);
+ }
+ return p_state->current_val;
+}
+
+void sensorsim_increment(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_cfg->max - p_state->current_val > p_cfg->incr)
+ {
+ p_state->current_val += p_cfg->incr;
+ }
+ else
+ {
+ p_state->current_val = p_cfg->max;
+ p_state->is_increasing = false;
+ }
+}
+
+
+void sensorsim_decrement(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_state->current_val - p_cfg->min > p_cfg->incr)
+ {
+ p_state->current_val -= p_cfg->incr;
+ }
+ else
+ {
+ p_state->current_val = p_cfg->min;
+ p_state->is_increasing = true;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h
new file mode 100644
index 0000000..af5e1cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup ble_sdk_lib_sensorsim Sensor Data Simulator
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Functions for simulating sensor data.
+ *
+ * @details Currently only a triangular waveform simulator is implemented.
+ */
+
+#ifndef SENSORSIM_H__
+#define SENSORSIM_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Triangular waveform sensor simulator configuration. */
+typedef struct
+{
+ uint32_t min; /**< Minimum simulated value. */
+ uint32_t max; /**< Maximum simulated value. */
+ uint32_t incr; /**< Increment between each measurement. */
+ bool start_at_max; /**< TRUE is measurement is to start at the maximum value, FALSE if it is to start at the minimum. */
+} sensorsim_cfg_t;
+
+/**@brief Triangular waveform sensor simulator state. */
+typedef struct
+{
+ uint32_t current_val; /**< Current sensor value. */
+ bool is_increasing; /**< TRUE if the simulator is in increasing state, FALSE otherwise. */
+} sensorsim_state_t;
+
+/**@brief Function for initializing a triangular waveform sensor simulator.
+ *
+ * @param[out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ */
+void sensorsim_init(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+/**@brief Function for generating a simulated sensor measurement using a triangular waveform generator.
+ *
+ * @param[in,out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ *
+ * @return Simulator output.
+ */
+uint32_t sensorsim_measure(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+/**@brief Function for incrementing a simulated sensor measurement value.
+ *
+ * @param[in,out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ *
+ * @return Simulator output.
+ */
+void sensorsim_increment(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+/**@brief Function for decrementing a simulated sensor measurement value.
+ *
+ * @param[in,out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ *
+ * @return Simulator output.
+ */
+void sensorsim_decrement(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SENSORSIM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c
new file mode 100644
index 0000000..9cf89b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c
@@ -0,0 +1,675 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SERIAL)
+#include "nrf_serial.h"
+
+#if defined (UART_PRESENT)
+
+static void event_handler(nrf_serial_t const * p_serial,
+ nrf_serial_event_t event)
+{
+ if (p_serial->p_ctx->p_config->ev_handler)
+ {
+ p_serial->p_ctx->p_config->ev_handler(p_serial, event);
+ }
+}
+
+static void sleep_handler(nrf_serial_t const * p_serial)
+{
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ return;
+ }
+
+ if (p_serial->p_ctx->p_config->sleep_handler)
+ {
+ p_serial->p_ctx->p_config->sleep_handler();
+ }
+}
+
+static size_t serial_rx(nrf_serial_t const * p_serial,
+ uint8_t * p_buff,
+ size_t length)
+{
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ size_t rx_len = MIN(length, UINT8_MAX);
+ size_t len = rx_len;
+
+ while (nrf_drv_uart_rx_ready(&p_serial->instance) && len)
+ {
+ ret_code_t ret = nrf_drv_uart_rx(&p_serial->instance, p_buff, 1);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ p_buff++;
+ len--;
+ }
+
+ return rx_len - len;
+ }
+
+ nrf_queue_t const * p_rxq = p_serial->p_ctx->p_config->p_queues->p_rxq;
+ return nrf_queue_out(p_rxq, p_buff, length);
+}
+
+static size_t serial_tx(nrf_serial_t const * p_serial,
+ uint8_t const * p_buff,
+ size_t length)
+{
+ size_t tx_len = 0;
+
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ tx_len = MIN(length, UINT8_MAX);
+ ret_code_t ret = nrf_drv_uart_tx(&p_serial->instance, p_buff, tx_len);
+ ASSERT(ret == NRF_SUCCESS)
+ return tx_len;
+ }
+
+ nrf_queue_t const * p_txq = p_serial->p_ctx->p_config->p_queues->p_txq;
+ nrf_serial_buffers_t const * p_buffs = p_serial->p_ctx->p_config->p_buffers;
+
+ /* Try to enqueue data. */
+ size_t queue_in_len = nrf_queue_in(p_txq, p_buff, length);
+ if (nrf_drv_uart_tx_in_progress(&p_serial->instance))
+ {
+ return queue_in_len;
+ }
+
+ size_t len = nrf_queue_out(p_txq, p_buffs->p_txb, p_buffs->tx_size);
+ ASSERT(len > 0);
+ ret_code_t ret = nrf_drv_uart_tx(&p_serial->instance, p_buffs->p_txb, len);
+ ASSERT(ret == NRF_SUCCESS);
+
+ return queue_in_len;
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ uint32_t ret;
+ nrf_serial_t const * p_serial = p_context;
+
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ {
+ nrf_queue_t const * p_rxq =
+ p_serial->p_ctx->p_config->p_queues->p_rxq;
+ size_t len = nrf_queue_in(p_rxq,
+ p_event->data.rxtx.p_data,
+ p_event->data.rxtx.bytes);
+
+ if (len < p_event->data.rxtx.bytes)
+ {
+ event_handler(p_serial, NRF_SERIAL_EVENT_FIFO_ERR);
+ break;
+ }
+
+ event_handler(p_serial, NRF_SERIAL_EVENT_RX_DATA);
+ nrf_serial_buffers_t const * p_buffs =
+ p_serial->p_ctx->p_config->p_buffers;
+
+ ret = nrf_drv_uart_rx(&p_serial->instance,
+ p_buffs->p_rxb,
+ p_buffs->rx_size);
+ ASSERT(ret == NRF_SUCCESS);
+ break;
+ }
+ case NRF_DRV_UART_EVT_ERROR:
+ {
+ event_handler(p_serial, NRF_SERIAL_EVENT_DRV_ERR);
+ break;
+ }
+ case NRF_DRV_UART_EVT_TX_DONE:
+ {
+ nrf_queue_t const * p_txq =
+ p_serial->p_ctx->p_config->p_queues->p_txq;
+ nrf_serial_buffers_t const * p_buffs =
+ p_serial->p_ctx->p_config->p_buffers;
+
+ event_handler(p_serial, NRF_SERIAL_EVENT_TX_DONE);
+ size_t len = nrf_queue_out(p_txq, p_buffs->p_txb, p_buffs->tx_size);
+ if (len == 0)
+ {
+ break;
+ }
+
+ ret = nrf_drv_uart_tx(&p_serial->instance, p_buffs->p_txb, len);
+ ASSERT(ret == NRF_SUCCESS);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
+ nrf_drv_uart_config_t const * p_drv_uart_config,
+ nrf_serial_config_t const * p_config)
+{
+ ret_code_t ret;
+ ASSERT(p_serial && p_drv_uart_config && p_config);
+
+ if (p_serial->p_ctx->p_config)
+ {
+ /*Already initialized.*/
+ return NRF_ERROR_MODULE_ALREADY_INITIALIZED;
+ }
+
+ if (p_config->mode != NRF_SERIAL_MODE_POLLING)
+ {
+ ASSERT(p_config->p_queues && p_config->p_buffers);
+ }
+
+ nrf_drv_uart_config_t drv_config;
+ memcpy(&drv_config, p_drv_uart_config, sizeof(nrf_drv_uart_config_t));
+ drv_config.p_context = (void *)p_serial;
+#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
+ drv_config.use_easy_dma = (p_config->mode == NRF_SERIAL_MODE_DMA);
+#endif
+ ret = nrf_drv_uart_init(&p_serial->instance,
+ &drv_config,
+ p_config->mode == NRF_SERIAL_MODE_POLLING ?
+ NULL : uart_event_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ p_serial->p_ctx->p_config = p_config;
+
+ if (p_serial->p_ctx->p_config->p_queues)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq);
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq);
+ }
+
+ nrf_mtx_init(&p_serial->p_ctx->read_lock);
+ nrf_mtx_init(&p_serial->p_ctx->write_lock);
+
+ p_serial->p_ctx->flags = NRF_SERIAL_RX_ENABLED_FLAG |
+ NRF_SERIAL_TX_ENABLED_FLAG;
+
+ if (drv_config.pseltxd == NRF_UART_PSEL_DISCONNECTED)
+ {
+ p_serial->p_ctx->flags &= ~NRF_SERIAL_TX_ENABLED_FLAG;
+ }
+
+ if (drv_config.pselrxd == NRF_UART_PSEL_DISCONNECTED)
+ {
+ p_serial->p_ctx->flags &= ~NRF_SERIAL_RX_ENABLED_FLAG;
+ return NRF_SUCCESS;
+ }
+
+ if (p_serial->p_ctx->p_config->mode != NRF_SERIAL_MODE_DMA)
+ {
+ nrf_drv_uart_rx_enable(&p_serial->instance);
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+
+ return nrf_drv_uart_rx(&p_serial->instance,
+ p_serial->p_ctx->p_config->p_buffers->p_rxb,
+ p_serial->p_ctx->p_config->p_buffers->rx_size);
+}
+
+ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial)
+{
+ ASSERT(p_serial);
+
+ if (!p_serial->p_ctx->p_config)
+ {
+ /*Already uninitialized.*/
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock))
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_drv_uart_uninit(&p_serial->instance);
+ if (p_serial->p_ctx->p_config->p_queues)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq);
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq);
+ }
+
+ memset(p_serial->p_ctx, 0, sizeof(nrf_serial_ctx_t));
+ return NRF_SUCCESS;
+}
+
+typedef struct {
+ volatile bool expired;
+} nrf_serial_timeout_ctx_t;
+
+static void serial_timeout_handler(void * p_context)
+{
+ nrf_serial_timeout_ctx_t * p_tout_ctx = p_context;
+ p_tout_ctx->expired = true;
+}
+
+
+static ret_code_t timeout_setup(nrf_serial_t const * p_serial,
+ app_timer_id_t const * p_timer_id,
+ uint32_t timeout_ms,
+ nrf_serial_timeout_ctx_t * p_tout_ctx)
+{
+ uint32_t ticks = APP_TIMER_TICKS(timeout_ms);
+
+ if (ticks < APP_TIMER_MIN_TIMEOUT_TICKS)
+ {
+ p_tout_ctx->expired = true;
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = app_timer_create(p_timer_id,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ serial_timeout_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ return app_timer_start(*p_timer_id, ticks, p_tout_ctx);
+}
+
+ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
+ void const * p_data,
+ size_t size,
+ size_t * p_written,
+ uint32_t timeout_ms)
+{
+ ret_code_t ret;
+
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (size == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (!nrfx_is_in_ram(p_data) &&
+ p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_DMA)
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_serial_timeout_ctx_t tout_ctx = {
+ .expired = false,
+ };
+
+ if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)
+ {
+ ret = timeout_setup(p_serial,
+ p_serial->p_tx_timer,
+ timeout_ms,
+ &tout_ctx);
+ if (ret != NRF_SUCCESS)
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return ret;
+ }
+ }
+
+ size_t left = size;
+ uint8_t const * p_buff = p_data;
+
+ do
+ {
+ size_t wcnt = serial_tx(p_serial, p_buff, left);
+ left -= wcnt;
+ p_buff += wcnt;
+ if (!left)
+ {
+ break;
+ }
+
+ sleep_handler(p_serial);
+ } while (!tout_ctx.expired);
+
+ if (p_written)
+ {
+ *p_written = size - left;
+ }
+
+ if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT))
+ {
+ (void)app_timer_stop(*p_serial->p_tx_timer);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ if (left && tout_ctx.expired)
+ {
+ return NRF_ERROR_TIMEOUT;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
+ void * p_data,
+ size_t size,
+ size_t * p_read,
+ uint32_t timeout_ms)
+{
+ ret_code_t ret;
+
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_RX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (size == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_serial_timeout_ctx_t tout_ctx = {
+ .expired = false,
+ };
+
+ if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)
+ {
+ ret = timeout_setup(p_serial,
+ p_serial->p_rx_timer,
+ timeout_ms,
+ &tout_ctx);
+
+ if (ret != NRF_SUCCESS)
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->read_lock);
+ return ret;
+ }
+ }
+
+ size_t left = size;
+ uint8_t * p_buff = p_data;
+ do
+ {
+ size_t rcnt = serial_rx(p_serial, p_buff, left);
+ left -= rcnt;
+ p_buff += rcnt;
+ if (!left)
+ {
+ break;
+ }
+
+ if (tout_ctx.expired)
+ {
+ if (p_serial->p_ctx->p_config->mode != NRF_SERIAL_MODE_POLLING)
+ {
+ nrf_drv_uart_rx_abort(&p_serial->instance);
+ }
+ break;
+ }
+
+ sleep_handler(p_serial);
+ } while (1);
+
+ if (p_read)
+ {
+ *p_read = size - left;
+ }
+
+ if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT))
+ {
+ (void)app_timer_stop(*p_serial->p_rx_timer);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->read_lock);
+ if (left && tout_ctx.expired)
+ {
+ return NRF_ERROR_TIMEOUT;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms)
+{
+
+ ret_code_t ret;
+
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_serial_timeout_ctx_t tout_ctx = {
+ .expired = false,
+ };
+
+ if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)
+ {
+ ret = timeout_setup(p_serial,
+ p_serial->p_tx_timer,
+ timeout_ms,
+ &tout_ctx);
+ if (ret != NRF_SUCCESS)
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return ret;
+ }
+ }
+
+ bool empty;
+ do
+ {
+ empty = nrf_queue_is_empty(p_serial->p_ctx->p_config->p_queues->p_txq)
+ && !nrf_drv_uart_tx_in_progress(&p_serial->instance);
+ if (empty)
+ {
+ break;
+ }
+
+ sleep_handler(p_serial);
+ } while (!tout_ctx.expired);
+
+ if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT))
+ {
+ (void)app_timer_stop(*p_serial->p_tx_timer);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ if (!empty && tout_ctx.expired)
+ {
+ return NRF_ERROR_TIMEOUT;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial)
+{
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_drv_uart_tx_abort(&p_serial->instance);
+ if (p_serial->p_ctx->p_config->p_queues->p_txq)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial)
+{
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_RX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint8_t c;
+ /*Drain HW FIFO*/
+ while (serial_rx(p_serial, &c, sizeof(c)))
+ {
+
+ }
+
+ /*Drain SW FIFO*/
+ if (p_serial->p_ctx->p_config->p_queues->p_rxq)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq);
+ }
+ nrf_mtx_unlock(&p_serial->p_ctx->read_lock);
+ return NRF_SUCCESS;
+}
+#else
+ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
+ nrf_drv_uart_config_t const * p_drv_uart_config,
+ nrf_serial_config_t const * p_config)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
+ void const * p_data,
+ size_t size,
+ size_t * p_written,
+ uint32_t timeout_ms)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
+ void * p_data,
+ size_t size,
+ size_t * p_read,
+ uint32_t timeout_ms)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+#endif // UART_PRESENT
+#endif //NRF_MODULE_ENABLED(NRF_SERIAL)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h
new file mode 100644
index 0000000..167e373
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h
@@ -0,0 +1,397 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_SERIAL_H__
+#define NRF_SERIAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_uart.h"
+#include "nrf_queue.h"
+#include "nrf_mtx.h"
+#include "app_timer.h"
+
+/**@file
+ *
+ * @defgroup nrf_serial Serial port abstraction layer
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Serial module interface.
+ * @details This module is more sophisticated than @ref nrf_drv_uart. It internally uses
+ * mutex, queues, and app_timer. You can configure it to work in three different modes
+ * (polling, interrupt, DMA). API can be configured to work in synchronous mode. Both read and write
+ * methods have a timeout parameter. Asynchronous mode is available by passing 0 as the
+ * timeout parameter.
+ * @warning Do not use synchronous API (timeout_ms parameter > 0) in IRQ
+ * context. It may lead to a deadlock because the timeout interrupt cannot
+ * preempt the current IRQ context.
+ */
+
+typedef struct nrf_serial_s nrf_serial_t;
+
+/**
+ * @brief Serial port mode.
+ * */
+typedef enum {
+ NRF_SERIAL_MODE_POLLING, /**< Polling mode.*/
+ NRF_SERIAL_MODE_IRQ, /**< Interrupt mode.*/
+ NRF_SERIAL_MODE_DMA, /**< DMA mode.*/
+} nrf_serial_mode_t;
+
+
+
+/**
+ * @brief Creates an instance of @ref nrf_drv_uart_config_t.
+ *
+ * @param _name Instance name.
+ * @param _rx_pin RX pin number.
+ * @param _tx_pin TX pin number.
+ * @param _rts_pin RTS pin number.
+ * @param _cts_pin CTS pin number.
+ * @param _flow_control Flow control enable/disable (@ref nrf_uart_hwfc_t).
+ * @param _parity Parity enable/disable (@ref nrf_uart_parity_t).
+ * @param _baud_rate Baud rate (@ref nrf_uart_baudrate_t).
+ * @param _irq_prio Interrupt priority.
+ *
+ * */
+#define NRF_SERIAL_DRV_UART_CONFIG_DEF(_name, \
+ _rx_pin, \
+ _tx_pin, \
+ _rts_pin, \
+ _cts_pin, \
+ _flow_control, \
+ _parity, \
+ _baud_rate, \
+ _irq_prio) \
+ static const nrf_drv_uart_config_t _name = { \
+ .pselrxd = _rx_pin, \
+ .pseltxd = _tx_pin, \
+ .pselrts = _rts_pin, \
+ .pselcts = _cts_pin, \
+ .hwfc = _flow_control, \
+ .parity = _parity, \
+ .baudrate = _baud_rate, \
+ .interrupt_priority = _irq_prio, \
+ }
+
+/**
+ * @brief Serial port RX and TX queues.
+ *
+ * @note Use the @ref NRF_SERIAL_QUEUES_DEF macro to create an instance of this
+ * structure.
+ * */
+typedef struct {
+ nrf_queue_t const * p_rxq; //!< Receive queue handle.
+ nrf_queue_t const * p_txq; //!< Transmit queue handle.
+} nrf_serial_queues_t;
+
+/**
+ * @brief Creates an instance of serial port queues.
+ *
+ * @param _name Instance name.
+ * @param _tx_size TX queue size.
+ * @param _rx_size RX queue size.
+ * */
+#define NRF_SERIAL_QUEUES_DEF(_name, _tx_size, _rx_size) \
+ NRF_QUEUE_DEF(uint8_t, _name##_rxq, _rx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \
+ NRF_QUEUE_DEF(uint8_t, _name##_txq, _tx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static const nrf_serial_queues_t _name = { \
+ .p_rxq = &_name##_rxq, \
+ .p_txq = &_name##_txq, \
+ }
+
+/**
+ * @brief Serial buffers. Data slices used by @ref nrf_drv_uart_tx and
+ * @ref nrf_drv_uart_rx.
+ *
+ * @note Use the @ref NRF_SERIAL_BUFFERS_DEF macro to create an instance of this
+ * structure.
+ * */
+typedef struct {
+ void * p_txb; //!< TX buffer.
+ void * p_rxb; //!< RX buffer.
+ uint8_t tx_size; //!< TX buffer size.
+ uint8_t rx_size; //!< RX buffer size.
+} nrf_serial_buffers_t;
+
+/**
+ * @brief Creates an instance of serial port buffers.
+ *
+ * @param _name Instance name.
+ * @param _tx_size TX buffer size.
+ * @param _rx_size RX buffer size.
+ * */
+#define NRF_SERIAL_BUFFERS_DEF(_name, _tx_size, _rx_size) \
+ STATIC_ASSERT((_tx_size) <= UINT8_MAX); \
+ STATIC_ASSERT((_rx_size) <= UINT8_MAX); \
+ static uint8_t _name##_txb[_tx_size]; \
+ static uint8_t _name##_rxb[_rx_size]; \
+ static const nrf_serial_buffers_t _name = { \
+ .p_txb = _name##_txb, \
+ .p_rxb = _name##_rxb, \
+ .tx_size = sizeof(_name##_txb), \
+ .rx_size = sizeof(_name##_rxb), \
+ }
+
+/**
+ * @brief Events generated by this module.
+ * */
+typedef enum {
+ NRF_SERIAL_EVENT_TX_DONE, //!< Chunk of data has been sent.
+ NRF_SERIAL_EVENT_RX_DATA, //!< New chunk of data has been received.
+ NRF_SERIAL_EVENT_DRV_ERR, //!< Internal driver error.
+ NRF_SERIAL_EVENT_FIFO_ERR, //!< RX FIFO overrun.
+} nrf_serial_event_t;
+
+/**
+ * @brief Event handler type.
+ * */
+typedef void (*nrf_serial_evt_handler_t)(struct nrf_serial_s const * p_serial,
+ nrf_serial_event_t event);
+
+/**
+ * @brief Sleep handler type.
+ * */
+typedef void (*nrf_serial_sleep_handler_t)(void);
+
+/**
+ * @brief Configuration of UART serial interface.
+ *
+ * @note Use the @ref NRF_SERIAL_CONFIG_DEF macro to create an instance of this
+ * structure.
+ *
+ */
+typedef struct {
+ nrf_serial_mode_t mode; //!< Serial port mode.
+
+ nrf_serial_queues_t const * p_queues; //!< Serial port queues.
+ nrf_serial_buffers_t const * p_buffers; //!< DMA buffers.
+ nrf_serial_evt_handler_t ev_handler; //!< Event handler.
+ nrf_serial_sleep_handler_t sleep_handler; //!< Sleep mode handler.
+} nrf_serial_config_t;
+
+/**
+ * @brief Creates an instance of serial port configuration.
+ *
+ * @param _name Instance name.
+ * @param _mode Serial port mode.
+ * @param _queues Serial port queues. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode.
+ * @param _buffers Serial port buffers. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode.
+ * @param _ev_handler Serial port event handler. NULL can be passed in any mode.
+ * @param _sleep Serial port sleep handler. NULL can be passed in any mode.
+ * */
+#define NRF_SERIAL_CONFIG_DEF(_name, _mode, _queues, _buffers, _ev_handler, _sleep) \
+ static const nrf_serial_config_t _name = { \
+ .mode = _mode, \
+ .p_queues = _queues, \
+ .p_buffers = _buffers, \
+ .ev_handler = _ev_handler, \
+ .sleep_handler = _sleep, \
+ }
+
+#define NRF_SERIAL_RX_ENABLED_FLAG (1u << 0) //!< Receiver enable flag.
+#define NRF_SERIAL_TX_ENABLED_FLAG (1u << 1) //!< Transmitter enable flag.
+
+/**
+ * @brief Serial port context. Contains all data structures that need
+ * to be stored in RAM memory.
+ * */
+typedef struct {
+ nrf_serial_config_t const * p_config; //!< Serial port configuration.
+
+ nrf_mtx_t write_lock; //!< Write operation lock.
+ nrf_mtx_t read_lock; //!< Read operation lock.
+
+ uint8_t flags; //!< Transmitter/receiver enable flags.
+} nrf_serial_ctx_t;
+
+/**
+ * @brief Serial port instance declaration.
+ *
+ * @note Use @ref NRF_SERIAL_UART_DEF macro to create an instance of this
+ * structure.
+ * */
+struct nrf_serial_s {
+ nrf_drv_uart_t instance; //!< Driver instance.
+ nrf_serial_ctx_t * p_ctx; //!< Driver context.
+
+ app_timer_id_t const * p_tx_timer; //!< TX timeout timer.
+ app_timer_id_t const * p_rx_timer; //!< RX timeout timer.
+};
+
+/**
+ * @brief Creates an instance of a serial port.
+ *
+ * @param _name Instance name.
+ * @param _instance_number Driver instance number (@ref NRF_DRV_UART_INSTANCE).
+ * */
+#define NRF_SERIAL_UART_DEF(_name, _instance_number) \
+ APP_TIMER_DEF(_name##_rx_timer); \
+ APP_TIMER_DEF(_name##_tx_timer); \
+ static nrf_serial_ctx_t _name##_ctx; \
+ static const nrf_serial_t _name = { \
+ .instance = NRF_DRV_UART_INSTANCE(_instance_number), \
+ .p_ctx = &_name##_ctx, \
+ .p_tx_timer = &_name##_tx_timer, \
+ .p_rx_timer = &_name##_rx_timer, \
+ }
+
+
+/**
+ * @brief Maximum value of timeout. API might be blocked indefinitely if this value is
+ * not set.*/
+#define NRF_SERIAL_MAX_TIMEOUT UINT32_MAX
+
+/**
+ * @brief Function for initializing a serial port. Serial port can be initialized
+ * in various modes that are defined by nrf_serial_mode_t.
+ * - NRF_SERIAL_MODE_POLLING - Simple polling mode. API calls will be
+ * synchronous. There is no need to define queues or buffers.
+ * No events will be generated.
+ * - NRF_SERIAL_MODE_IRQ - Interrupt mode. API can be set to work in synchronous or
+ * asynchronous mode. Queues and buffers must be passed
+ * during initialization. Events will be generated if
+ * a non NULL handler is passed as the ev_handler parameter.
+ * - NRF_SERIAL_MODE_DMA - Similar to @ref NRF_SERIAL_MODE_IRQ. Uses EasyDMA.
+ *
+ *
+ * @param p_serial Serial port instance.
+ * @param p_drv_uart_config UART driver configuration. Cannot be NULL.
+ * @param p_config Serial port configuration. Cannot be NULL. This object must be created
+ * using the @ref NRF_SERIAL_CONFIG_DEF macro.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
+ nrf_drv_uart_config_t const * p_drv_uart_config,
+ nrf_serial_config_t const * p_config);
+
+
+/**
+ * @brief Function for uninitializing a serial port.
+ *
+ * @param p_serial Serial port instance.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial);
+
+
+/**
+ * @brief Function for writing to a serial port.
+ *
+ * @param p_serial Serial port instance.
+ * @param p_data Transmit buffer pointer.
+ * @param size Transmit buffer size.
+ * @param p_written Amount of data actually written to the serial port.
+ * NULL pointer can be passed.
+ * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
+ * non blocking mode.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
+ void const * p_data,
+ size_t size,
+ size_t * p_written,
+ uint32_t timeout_ms);
+
+/**
+ * @brief Function for reading from a serial port.
+ *
+ * @param p_serial Serial port instance.
+ * @param p_data Receive buffer pointer.
+ * @param size Receive buffer size.
+ * @param p_read Amount of data actually read from the serial port.
+ * NULL pointer can be passed.
+ * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
+ * non blocking mode.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
+ void * p_data,
+ size_t size,
+ size_t * p_read,
+ uint32_t timeout_ms);
+
+/**
+ * @brief Function for flushing a serial port TX queue.
+ *
+ * @param p_serial Serial port instance.
+ * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
+ * non blocking mode.
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms);
+
+
+/**
+ * @brief Function for aborting a serial port transmission.
+ * Aborts the current ongoing transmission and resets TX FIFO.
+ *
+ * @param p_serial Serial port instance.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial);
+
+/**
+ * @brief Function for draining the serial port receive RX FIFO.
+ * Drains HW FIFO and resets RX FIFO.
+ *
+ * @param p_serial Serial port instance.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SERIAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c
new file mode 100644
index 0000000..8cc6b76
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdlib.h>
+#include "sha256.h"
+#include "sdk_errors.h"
+#include "sdk_common.h"
+
+
+#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32 - (b))))
+
+#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
+#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
+#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
+#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
+#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
+
+
+static const uint32_t k[64] = {
+ 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
+ 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
+ 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
+ 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
+ 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
+ 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
+ 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
+ 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+};
+
+
+/**@brief Function for calculating the hash of a 64-byte section of data.
+ *
+ * @param[in,out] ctx Hash instance.
+ * @param[in] data Aray with data to be hashed. Assumed to be 64 bytes long.
+ */
+void sha256_transform(sha256_context_t *ctx, const uint8_t * data)
+{
+ uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
+
+ for (i = 0, j = 0; i < 16; ++i, j += 4)
+ m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
+ for ( ; i < 64; ++i)
+ m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
+
+ a = ctx->state[0];
+ b = ctx->state[1];
+ c = ctx->state[2];
+ d = ctx->state[3];
+ e = ctx->state[4];
+ f = ctx->state[5];
+ g = ctx->state[6];
+ h = ctx->state[7];
+
+ for (i = 0; i < 64; ++i) {
+ t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
+ t2 = EP0(a) + MAJ(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+
+ ctx->state[0] += a;
+ ctx->state[1] += b;
+ ctx->state[2] += c;
+ ctx->state[3] += d;
+ ctx->state[4] += e;
+ ctx->state[5] += f;
+ ctx->state[6] += g;
+ ctx->state[7] += h;
+}
+
+
+ret_code_t sha256_init(sha256_context_t *ctx)
+{
+ VERIFY_PARAM_NOT_NULL(ctx);
+
+ ctx->datalen = 0;
+ ctx->bitlen = 0;
+ ctx->state[0] = 0x6a09e667;
+ ctx->state[1] = 0xbb67ae85;
+ ctx->state[2] = 0x3c6ef372;
+ ctx->state[3] = 0xa54ff53a;
+ ctx->state[4] = 0x510e527f;
+ ctx->state[5] = 0x9b05688c;
+ ctx->state[6] = 0x1f83d9ab;
+ ctx->state[7] = 0x5be0cd19;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, size_t len)
+{
+ VERIFY_PARAM_NOT_NULL(ctx);
+ if (((len > 0) && (data == NULL)))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t i;
+
+ for (i = 0; i < len; ++i) {
+ ctx->data[ctx->datalen] = data[i];
+ ctx->datalen++;
+ if (ctx->datalen == 64) {
+ sha256_transform(ctx, ctx->data);
+ ctx->bitlen += 512;
+ ctx->datalen = 0;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le)
+{
+ uint32_t i;
+
+ VERIFY_PARAM_NOT_NULL(ctx);
+ VERIFY_PARAM_NOT_NULL(hash);
+
+ i = ctx->datalen;
+
+ // Pad whatever data is left in the buffer.
+ if (ctx->datalen < 56) {
+ ctx->data[i++] = 0x80;
+ while (i < 56)
+ ctx->data[i++] = 0x00;
+ }
+ else {
+ ctx->data[i++] = 0x80;
+ while (i < 64)
+ ctx->data[i++] = 0x00;
+ sha256_transform(ctx, ctx->data);
+ memset(ctx->data, 0, 56);
+ }
+
+ // Append to the padding the total message's length in bits and transform.
+ ctx->bitlen += (uint64_t)ctx->datalen * 8;
+ ctx->data[63] = ctx->bitlen;
+ ctx->data[62] = ctx->bitlen >> 8;
+ ctx->data[61] = ctx->bitlen >> 16;
+ ctx->data[60] = ctx->bitlen >> 24;
+ ctx->data[59] = ctx->bitlen >> 32;
+ ctx->data[58] = ctx->bitlen >> 40;
+ ctx->data[57] = ctx->bitlen >> 48;
+ ctx->data[56] = ctx->bitlen >> 56;
+ sha256_transform(ctx, ctx->data);
+
+ if (le)
+ {
+ for (i = 0; i < 4; ++i) {
+ hash[i] = (ctx->state[7] >> (i * 8)) & 0x000000ff;
+ hash[i + 4] = (ctx->state[6] >> (i * 8)) & 0x000000ff;
+ hash[i + 8] = (ctx->state[5] >> (i * 8)) & 0x000000ff;
+ hash[i + 12] = (ctx->state[4] >> (i * 8)) & 0x000000ff;
+ hash[i + 16] = (ctx->state[3] >> (i * 8)) & 0x000000ff;
+ hash[i + 20] = (ctx->state[2] >> (i * 8)) & 0x000000ff;
+ hash[i + 24] = (ctx->state[1] >> (i * 8)) & 0x000000ff;
+ hash[i + 28] = (ctx->state[0] >> (i * 8)) & 0x000000ff;
+ }
+ }
+ else
+ {
+
+ // Since this implementation uses little endian uint8_t ordering and SHA uses big endian,
+ // reverse all the uint8_ts when copying the final state to the output hash.
+ for (i = 0; i < 4; ++i) {
+ hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h
new file mode 100644
index 0000000..8be5786
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup sha256 SHA-256 hash library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief This module calculates SHA-256 (SHA-2, FIPS-180) hashes.
+ *
+ * @details To use this module, first call @ref sha256_init on a @ref sha256_context_t instance. Then call @ref
+ * sha256_update with the data to be hashed. This step can optionally be done with multiple
+ * calls to @ref sha256_update, each with a section of the data (in the correct order).
+ * After all data has been passed to @ref sha256_update, call @ref sha256_final to finalize
+ * and extract the hash value.
+ *
+ * This code is adapted from code by Brad Conte, retrieved from
+ * https://github.com/B-Con/crypto-algorithms.
+ *
+ */
+
+#ifndef SHA256_H
+#define SHA256_H
+
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Current state of a hash operation.
+ */
+typedef struct {
+ uint8_t data[64];
+ uint32_t datalen;
+ uint64_t bitlen;
+ uint32_t state[8];
+} sha256_context_t;
+
+
+/**@brief Function for initializing a @ref sha256_context_t instance.
+ *
+ * @param[out] ctx Context instance to be initialized.
+ *
+ * @retval NRF_SUCCESS If the instance was successfully initialized.
+ * @retval NRF_ERROR_NULL If the parameter was NULL.
+ */
+ret_code_t sha256_init(sha256_context_t *ctx);
+
+/**@brief Function for calculating the hash of an array of uint8_t data.
+ *
+ * @details This function can be called multiple times in sequence. This is equivalent to calling
+ * the function once on a concatenation of the data from the different calls.
+ *
+ * @param[in,out] ctx Hash instance.
+ * @param[in] data Data to be hashed.
+ * @param[in] len Length of the data to be hashed.
+ *
+ * @retval NRF_SUCCESS If the data was successfully hashed.
+ * @retval NRF_ERROR_NULL If the ctx parameter was NULL or the data parameter was NULL, while the len parameter was not zero.
+ */
+ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, const size_t len);
+
+/**@brief Function for extracting the hash value from a hash instance.
+ *
+ * @details This function should be called after all data to be hashed has been passed to the hash
+ * instance (by one or more calls to @ref sha256_update).
+ *
+ * Do not call @ref sha256_update again after @ref sha256_final has been called.
+ *
+ * @param[in,out] ctx Hash instance.
+ * @param[out] hash Array to hold the extracted hash value (assumed to be 32 bytes long).
+ * @param[in] le Store the hash in little-endian.
+ *
+ * @retval NRF_SUCCESS If the has value was successfully extracted.
+ * @retval NRF_ERROR_NULL If a parameter was NULL.
+ */
+ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SHA256_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c
new file mode 100644
index 0000000..f353f06
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(SIMPLE_TIMER)
+#include "app_simple_timer.h"
+#include "nrf.h"
+#include "app_util_platform.h"
+#include "app_error.h"
+#include "nrf_timer.h"
+#include "nrf_drv_timer.h"
+
+/**@brief States of simple timer state machine.
+ */
+typedef enum
+{
+ SIMPLE_TIMER_STATE_IDLE = 0,
+ SIMPLE_TIMER_STATE_INITIALIZED,
+ SIMPLE_TIMER_STATE_STOPPED,
+ SIMPLE_TIMER_STATE_STARTED
+}simple_timer_states_t;
+
+static app_simple_timer_mode_t m_mode; /**< Registered timer mode. */
+static app_simple_timer_timeout_handler_t m_timeout_handler = NULL; /**< Registered time-out handler. */
+static void * mp_timeout_handler_context = NULL; /**< Registered time-out handler context. */
+static simple_timer_states_t m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE; /**< State machine state. */
+
+const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(SIMPLE_TIMER_CONFIG_INSTANCE);
+
+/**
+ * @brief Handler for timer events.
+ */
+static void app_simple_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
+{
+ switch (event_type)
+ {
+ case NRF_TIMER_EVENT_COMPARE0:
+ if (m_mode == APP_SIMPLE_TIMER_MODE_SINGLE_SHOT)
+ {
+ m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;
+ }
+
+ //@note: No NULL check required as performed in timer_start(...).
+ m_timeout_handler(mp_timeout_handler_context);
+ break;
+
+ default:
+ //Do nothing.
+ break;
+ }
+}
+
+uint32_t app_simple_timer_init(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ nrf_drv_timer_config_t t_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
+ t_cfg.mode = NRF_TIMER_MODE_TIMER;
+ t_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16;
+ t_cfg.frequency = (nrf_timer_frequency_t)SIMPLE_TIMER_CONFIG_FREQUENCY;
+ err_code = nrf_drv_timer_init(&SIMPLE_TIMER, &t_cfg, app_simple_timer_event_handler);
+
+ if (NRF_SUCCESS == err_code)
+ {
+ m_simple_timer_state = SIMPLE_TIMER_STATE_INITIALIZED;
+ }
+
+ return err_code;
+}
+
+uint32_t app_simple_timer_start(app_simple_timer_mode_t mode,
+ app_simple_timer_timeout_handler_t timeout_handler,
+ uint16_t timeout_ticks,
+ void * p_context)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ nrf_timer_short_mask_t timer_short;
+
+ VERIFY_PARAM_NOT_NULL(timeout_handler);
+
+ if (APP_SIMPLE_TIMER_MODE_REPEATED == mode)
+ {
+ timer_short = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK;
+ }
+ else if (APP_SIMPLE_TIMER_MODE_SINGLE_SHOT == mode)
+ {
+ timer_short = NRF_TIMER_SHORT_COMPARE0_STOP_MASK;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (SIMPLE_TIMER_STATE_IDLE == m_simple_timer_state)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state)
+ {
+ err_code = app_simple_timer_stop();
+ APP_ERROR_CHECK(err_code);
+ }
+
+ if (SIMPLE_TIMER_STATE_STOPPED == m_simple_timer_state)
+ {
+ nrf_drv_timer_clear(&SIMPLE_TIMER);
+ }
+
+ m_mode = mode;
+ m_timeout_handler = timeout_handler;
+ mp_timeout_handler_context = p_context;
+
+ nrf_drv_timer_extended_compare(
+ &SIMPLE_TIMER, NRF_TIMER_CC_CHANNEL0, (uint32_t)timeout_ticks, timer_short, true);
+
+ if (m_simple_timer_state == SIMPLE_TIMER_STATE_STOPPED)
+ {
+ nrf_drv_timer_resume(&SIMPLE_TIMER);
+ }
+ else
+ {
+ nrf_drv_timer_enable(&SIMPLE_TIMER);
+ }
+
+
+ m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t app_simple_timer_stop(void)
+{
+ if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state)
+ {
+ nrf_drv_timer_pause(&SIMPLE_TIMER);
+
+ m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t app_simple_timer_uninit(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (SIMPLE_TIMER_STATE_IDLE != m_simple_timer_state)
+ {
+ nrf_drv_timer_uninit(&SIMPLE_TIMER);
+ m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE;
+ }
+
+ return err_code;
+}
+#endif //NRF_MODULE_ENABLED(SIMPLE_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h
new file mode 100644
index 0000000..f67191f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup app_simple_timer Simple Timer
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Simple timer module.
+ *
+ * Supported features and limitations:
+ * - Two modes: single shot mode and repeated mode.
+ * - No more than one timer can run simultaneously.
+ * - The timer is hard-coded to use the TIMER1 peripheral and compare channel 0.
+ */
+
+#ifndef TIMER_H__
+#define TIMER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Timer time-out handler type. */
+typedef void (*app_simple_timer_timeout_handler_t)(void * p_context);
+
+/**@brief Timer modes. */
+typedef enum
+{
+ APP_SIMPLE_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */
+ APP_SIMPLE_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */
+} app_simple_timer_mode_t;
+
+/**@brief Function for configuring and setting up the timer hardware.
+ *
+ * @note Timer frequency is configured statically.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ * @retval NRF_ERROR_INVALID_STATE If the operation fails because the timer is already initialized.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation fails because some configuration parameter is
+ * not valid.
+ */
+uint32_t app_simple_timer_init(void);
+
+/**@brief Function for starting a timer.
+ *
+ * @note If this function is called for a timer that is already running, the currently running
+ * timer is stopped before starting the new one.
+ *
+ * @param[in] mode Timer mode (see @ref app_simple_timer_mode_t).
+ * @param[in] timeout_handler Function to be executed when the timer expires
+ * (see @ref app_simple_timer_timeout_handler_t).
+ * @param[in] timeout_ticks Number of timer ticks to time-out event.
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ * @retval NRF_ERROR_INVALID_STATE If the operation fails because @ref app_simple_timer_init has not
+ * been called and the operation is not allowed in this state.
+ * @retval NRF_ERROR_NULL If the operation fails because timeout_handler is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation fails because "mode" parameter is not valid.
+ */
+
+uint32_t app_simple_timer_start(app_simple_timer_mode_t mode,
+ app_simple_timer_timeout_handler_t timeout_handler,
+ uint16_t timeout_ticks,
+ void * p_context);
+
+/**@brief Function for stopping the timer.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ */
+uint32_t app_simple_timer_stop(void);
+
+/**@brief Function for uninitializing the timer. Should be called also when the timer is not used
+ * anymore to reach lowest power consumption in system.
+ *
+ * @note The function switches off the internal core of the timer to reach lowest power consumption
+ * in system. The startup time from this state may be longer compared to starting the timer
+ * from the stopped state.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ */
+uint32_t app_simple_timer_uninit(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TIMER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c
new file mode 100644
index 0000000..5e6e41b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(SLIP)
+#include "slip.h"
+
+#include <string.h>
+
+
+#define SLIP_BYTE_END 0300 /* indicates end of packet */
+#define SLIP_BYTE_ESC 0333 /* indicates byte stuffing */
+#define SLIP_BYTE_ESC_END 0334 /* ESC ESC_END means END data byte */
+#define SLIP_BYTE_ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */
+
+
+ret_code_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t * p_output_buffer_length)
+{
+ if (p_output == NULL || p_input == NULL || p_output_buffer_length == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ *p_output_buffer_length = 0;
+ uint32_t input_index;
+
+ for (input_index = 0; input_index < input_length; input_index++)
+ {
+ switch (p_input[input_index])
+ {
+ case SLIP_BYTE_END:
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC;
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC_END;
+ break;
+
+ case SLIP_BYTE_ESC:
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC;
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC_ESC;
+ break;
+
+ default:
+ p_output[(*p_output_buffer_length)++] = p_input[input_index];
+ }
+ }
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_END;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t slip_decode_add_byte(slip_t * p_slip, uint8_t c)
+{
+ if (p_slip == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (p_slip->current_index == p_slip->buffer_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ switch (p_slip->state)
+ {
+ case SLIP_STATE_DECODING:
+ switch (c)
+ {
+ case SLIP_BYTE_END:
+ // finished reading packet
+ return NRF_SUCCESS;
+
+ case SLIP_BYTE_ESC:
+ // wait for
+ p_slip->state = SLIP_STATE_ESC_RECEIVED;
+ break;
+
+ default:
+ // add byte to buffer
+ p_slip->p_buffer[p_slip->current_index++] = c;
+ break;
+ }
+ break;
+
+ case SLIP_STATE_ESC_RECEIVED:
+ switch (c)
+ {
+ case SLIP_BYTE_ESC_END:
+ p_slip->p_buffer[p_slip->current_index++] = SLIP_BYTE_END;
+ p_slip->state = SLIP_STATE_DECODING;
+ break;
+
+ case SLIP_BYTE_ESC_ESC:
+ p_slip->p_buffer[p_slip->current_index++] = SLIP_BYTE_ESC;
+ p_slip->state = SLIP_STATE_DECODING;
+ break;
+
+ default:
+ // protocol violation
+ p_slip->state = SLIP_STATE_CLEARING_INVALID_PACKET;
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+
+ case SLIP_STATE_CLEARING_INVALID_PACKET:
+ if (c == SLIP_BYTE_END)
+ {
+ p_slip->state = SLIP_STATE_DECODING;
+ p_slip->current_index = 0;
+ }
+ break;
+ }
+
+ return NRF_ERROR_BUSY;
+}
+#endif //NRF_MODULE_ENABLED(SLIP)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h
new file mode 100644
index 0000000..23791c0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SLIP_H__
+#define SLIP_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup slip SLIP encoding and decoding
+ * @{
+ * @ingroup app_common
+ *
+ * @brief This module encodes and decodes SLIP packages.
+ *
+ * @details The SLIP protocol is described in @linkSLIP.
+ */
+
+/** @brief Status information that is used while receiving and decoding a packet. */
+typedef enum
+{
+ SLIP_STATE_DECODING, //!< Ready to receive the next byte.
+ SLIP_STATE_ESC_RECEIVED, //!< An ESC byte has been received and the next byte must be decoded differently.
+ SLIP_STATE_CLEARING_INVALID_PACKET //!< The received data is invalid and transfer must be restarted.
+} slip_read_state_t;
+
+ /** @brief Representation of a SLIP packet. */
+typedef struct
+{
+ slip_read_state_t state; //!< Current state of the packet (see @ref slip_read_state_t).
+
+ uint8_t * p_buffer; //!< Decoded data.
+ uint32_t current_index; //!< Current length of the packet that has been received.
+ uint32_t buffer_len; //!< Size of the buffer that is available.
+} slip_t;
+
+/**@brief Function for encoding a SLIP packet.
+ *
+ * The maximum size of the output data is (2*input size + 1) bytes. Ensure that the provided buffer is large enough.
+ *
+ * @param[in,out] p_output The buffer where the encoded SLIP packet is stored. Ensure that it is large enough.
+ * @param[in,out] p_input The buffer to be encoded.
+ * @param[in,out] input_length The length of the input buffer.
+ * @param[out] p_output_buffer_length The length of the output buffer after the input has been encoded.
+ *
+ * @retval NRF_SUCCESS If the input was successfully encoded into output.
+ * @retval NRF_ERROR_NULL If one of the provided parameters is NULL.
+ */
+ret_code_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t * p_output_buffer_length);
+
+/**@brief Function for decoding a SLIP packet.
+ *
+ * The decoded packet is put into @p p_slip::p_buffer. The index and buffer state is updated.
+ *
+ * Ensure that @p p_slip is properly initialized. The initial state must be set to @ref SLIP_STATE_DECODING.
+ *
+ * @param[in,out] p_slip State of the decoding process.
+ * @param[in] c Byte to decode.
+ *
+ * @retval NRF_SUCCESS If a packet has been parsed. The received packet can be retrieved from @p p_slip.
+ * @retval NRF_ERROR_NULL If @p p_slip is NULL.
+ * @retval NRF_ERROR_NO_MEM If there is no more room in the buffer provided by @p p_slip.
+ * @retval NRF_ERROR_BUSY If the packet has not been parsed completely yet.
+ * @retval NRF_ERROR_INVALID_DATA If the packet is encoded wrong. In this case, @p p_slip::state is set to @ref SLIP_STATE_CLEARING_INVALID_PACKET,
+ * and decoding will stay in this state until the END byte is received.
+ */
+ret_code_t slip_decode_add_byte(slip_t * p_slip, uint8_t c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SLIP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c
new file mode 100644
index 0000000..b1cdd13
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SORTLIST)
+#include "nrf_sortlist.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME sortlist
+#if NRF_SORTLIST_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SORTLIST_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SORTLIST_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SORTLIST_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SORTLIST_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+void nrf_sortlist_add(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item)
+{
+ ASSERT(p_list);
+ ASSERT(p_item);
+
+ nrf_sortlist_item_t ** pp_curr = &(p_list->p_cb->p_head);
+
+ while(*pp_curr != NULL)
+ {
+ if(!(p_list->compare_func(*pp_curr, p_item)))
+ {
+ break;
+ }
+ pp_curr = &((*pp_curr)->p_next);
+ }
+
+ p_item->p_next = *pp_curr;
+ *pp_curr = p_item;
+
+ NRF_LOG_INFO("List:%s, adding element:%08X after:%08X, before:%08X",
+ p_list->p_name, p_item, *pp_curr, p_item->p_next);
+}
+
+nrf_sortlist_item_t * nrf_sortlist_pop(nrf_sortlist_t const * p_list)
+{
+ ASSERT(p_list);
+ nrf_sortlist_item_t * ret = p_list->p_cb->p_head;
+ if (p_list->p_cb->p_head != NULL)
+ {
+ p_list->p_cb->p_head = p_list->p_cb->p_head->p_next;
+ }
+ NRF_LOG_INFO("List:%s, poping element:%08X", p_list->p_name, ret);
+ return ret;
+}
+
+nrf_sortlist_item_t const * nrf_sortlist_peek(nrf_sortlist_t const * p_list)
+{
+ ASSERT(p_list);
+ return p_list->p_cb->p_head;
+}
+
+nrf_sortlist_item_t const * nrf_sortlist_next(nrf_sortlist_item_t const * p_item)
+{
+ ASSERT(p_item);
+ return p_item->p_next;
+}
+
+bool nrf_sortlist_remove(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item)
+{
+ ASSERT(p_list);
+ ASSERT(p_item);
+ bool ret = false;
+
+ nrf_sortlist_item_t ** pp_curr = &(p_list->p_cb->p_head);
+
+ while(*pp_curr != NULL)
+ {
+ if(*pp_curr == p_item)
+ {
+ *pp_curr = p_item->p_next;
+ ret = true;
+ break;
+ }
+ pp_curr = &((*pp_curr)->p_next);
+ }
+
+ NRF_LOG_INFO("List:%s, removing element:%08X %s",
+ p_list->p_name, p_item, ret ? "succeeded" : "not found");
+ return ret;
+}
+#endif //NRF_SORTLIST_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h
new file mode 100644
index 0000000..17de64a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_SORTLIST_H
+#define NRF_SORTLIST_H
+
+#include "sdk_config.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @defgroup nrf_sortlist Sorted list
+ * @{
+ * @ingroup app_common
+ * @brief Module for storing items in the ordered list.
+ */
+
+/**
+ * @brief Forward declaration of sorted list item.
+ */
+typedef struct nrf_sortlist_item_s nrf_sortlist_item_t;
+
+/** @brief Prototype of a function which compares two elements.
+ *
+ * @param p_item0 Item 0.
+ * @param p_item1 Item 1.
+ *
+ * @return True if Item 0 should be higher than Item 1 and false otherwise.
+ *
+ */
+typedef bool (*nrf_sortlist_compare_func_t)(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t * p_item1);
+
+/**
+ * @brief A structure for item in the sorted list.
+ */
+struct nrf_sortlist_item_s
+{
+ nrf_sortlist_item_t * p_next; /* Pointer to the next item in the list. */
+};
+
+/**
+ * @brief Sorted list instance control block.
+ *
+ * Control block contains instance data which must be located in read/write memory.
+ */
+typedef struct
+{
+ nrf_sortlist_item_t * p_head; /* List head.*/
+} nrf_sortlist_cb_t;
+/**
+ * @brief Structure for sorted list instance.
+ *
+ * Instance can be placed in read only memory.
+ */
+typedef struct
+{
+ char * p_name; /* List name. */
+ nrf_sortlist_cb_t * p_cb; /* List head.*/
+ nrf_sortlist_compare_func_t compare_func; /* Function used for comparison. */
+} nrf_sortlist_t;
+
+/**
+ * @brief Macro for conditionally including instance name.
+ *
+ * @param _name Instance name.
+ */
+#define NRF_SORTLIST_INST_NAME(_name) (NRF_LOG_ENABLED && NRF_SORTLIST_CONFIG_LOG_ENABLED) ? \
+ STRINGIFY(_name) : NULL
+/**
+ * @brief Macro for defining a sorted list instance.
+ *
+ * @param _name Instance name.
+ * @param _compare_func Pointer to a compare function.
+ */
+#define NRF_SORTLIST_DEF(_name, _compare_func) \
+ static nrf_sortlist_cb_t CONCAT_2(_name,_sortlist_cb) = { \
+ .p_head = NULL \
+ }; \
+ static const nrf_sortlist_t _name = { \
+ .p_name = NRF_SORTLIST_INST_NAME(_name), \
+ .p_cb = &CONCAT_2(_name,_sortlist_cb), \
+ .compare_func = _compare_func, \
+ }
+
+/**
+ * @brief Function for adding an element into a list.
+ *
+ * New item will be placed in the queue based on the compare function.
+ *
+ * @param p_list List instance.
+ * @param p_item Item.
+ */
+void nrf_sortlist_add(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item);
+
+/**
+ * @brief Function for removing an item from the list head.
+ *
+ * @param p_list List instance.
+ *
+ * @return Pointer to the item which was on the list head.
+ */
+nrf_sortlist_item_t * nrf_sortlist_pop(nrf_sortlist_t const * p_list);
+
+/**
+ * @brief Function for getting (without removing) an item from the list head.
+ *
+ * @param p_list List instance.
+ *
+ * @return Pointer to the item which is on the list head.
+ */
+nrf_sortlist_item_t const * nrf_sortlist_peek(nrf_sortlist_t const * p_list);
+
+/**
+ * @brief Function for iterating over the list.
+ *
+ * @param p_item Item in the list.
+ *
+ * @return Pointer to the next item in the list.
+ */
+nrf_sortlist_item_t const * nrf_sortlist_next(nrf_sortlist_item_t const * p_item);
+
+/**
+ * @brief Function for removing an item from the queue.
+ *
+ * @param p_list List instance.
+ * @param p_item Item.
+ *
+ * @retval true Item was found and removed.
+ * @retval false Item not found in the list.
+ */
+bool nrf_sortlist_remove(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_SORTLIST_H
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c
new file mode 100644
index 0000000..b66dfbb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c
@@ -0,0 +1,348 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_SPI_MNGR)
+#include "nrf_spi_mngr.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+
+typedef volatile struct
+{
+ bool transaction_in_progress;
+ uint8_t transaction_result;
+} nrf_spi_mngr_cb_data_t;
+
+static ret_code_t start_transfer(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ // use a local variable to avoid using two volatile variables in one
+ // expression
+ uint8_t curr_transfer_idx = p_nrf_spi_mngr->p_nrf_spi_mngr_cb->current_transfer_idx;
+ nrf_spi_mngr_transfer_t const * p_transfer =
+ &p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction->p_transfers[curr_transfer_idx];
+
+ return nrf_drv_spi_transfer(&p_nrf_spi_mngr->spi,
+ p_transfer->p_tx_data, p_transfer->tx_length,
+ p_transfer->p_rx_data, p_transfer->rx_length);
+}
+
+
+static void transaction_begin_signal(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ nrf_spi_mngr_transaction_t const * p_current_transaction =
+ p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction;
+
+
+ if (p_current_transaction->begin_callback != NULL)
+ {
+ void * p_user_data = p_current_transaction->p_user_data;
+ p_current_transaction->begin_callback(p_user_data);
+ }
+}
+
+
+static void transaction_end_signal(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ ret_code_t result)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ nrf_spi_mngr_transaction_t const * p_current_transaction =
+ p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction;
+
+ if (p_current_transaction->end_callback != NULL)
+ {
+ void * p_user_data = p_current_transaction->p_user_data;
+ p_current_transaction->end_callback(result, p_user_data);
+ }
+}
+
+
+static void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context);
+
+
+// This function starts pending transaction if there is no current one or
+// when 'switch_transaction' parameter is set to true. It is important to
+// switch to new transaction without setting 'p_nrf_spi_mngr->p_curr_transaction'
+// to NULL in between, since this pointer is used to check idle status - see
+// 'nrf_spi_mngr_is_idle()'.
+static void start_pending_transaction(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ bool switch_transaction)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ while (1)
+ {
+ bool start_transaction = false;
+ nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb;
+
+ CRITICAL_REGION_ENTER();
+ if (switch_transaction || nrf_spi_mngr_is_idle(p_nrf_spi_mngr))
+ {
+ if (nrf_queue_pop(p_nrf_spi_mngr->p_queue,
+ (void *)(&p_cb->p_current_transaction))
+ == NRF_SUCCESS)
+ {
+ start_transaction = true;
+ }
+ else
+ {
+ p_cb->p_current_transaction = NULL;
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (!start_transaction)
+ {
+ return;
+ }
+
+ nrf_drv_spi_config_t const * p_instance_cfg;
+ if (p_cb->p_current_transaction->p_required_spi_cfg == NULL)
+ {
+ p_instance_cfg = &p_cb->default_configuration;
+ }
+ else
+ {
+ p_instance_cfg = p_cb->p_current_transaction->p_required_spi_cfg;
+ }
+
+ ret_code_t result;
+
+ if (memcmp(p_cb->p_current_configuration, p_instance_cfg, sizeof(*p_instance_cfg)) != 0)
+ {
+ nrf_drv_spi_uninit(&p_nrf_spi_mngr->spi);
+ result = nrf_drv_spi_init(&p_nrf_spi_mngr->spi,
+ p_instance_cfg,
+ spi_event_handler,
+ (void *)p_nrf_spi_mngr);
+ ASSERT(result == NRF_SUCCESS);
+ p_cb->p_current_configuration = p_instance_cfg;
+ }
+
+ // Try to start first transfer for this new transaction.
+ p_cb->current_transfer_idx = 0;
+
+ // Execute user code if available before starting transaction
+ transaction_begin_signal(p_nrf_spi_mngr);
+ result = start_transfer(p_nrf_spi_mngr);
+
+ // If transaction started successfully there is nothing more to do here now.
+ if (result == NRF_SUCCESS)
+ {
+ return;
+ }
+
+ // Transfer failed to start - notify user that this transaction
+ // cannot be started and try with next one (in next iteration of
+ // the loop).
+ transaction_end_signal(p_nrf_spi_mngr, result);
+
+ switch_transaction = true;
+ }
+}
+
+
+// This function shall be called to handle SPI events. It shall be mainly used by SPI IRQ for
+// finished tranfer.
+static void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context)
+{
+ ASSERT(p_event != NULL);
+ ASSERT(p_context != NULL);
+
+ ret_code_t result;
+ nrf_spi_mngr_cb_t * p_cb = ((nrf_spi_mngr_t const *)p_context)->p_nrf_spi_mngr_cb;
+
+ // This callback should be called only during transaction.
+ ASSERT(p_cb->p_current_transaction != NULL);
+
+ if (p_event->type == NRF_DRV_SPI_EVENT_DONE)
+ {
+ result = NRF_SUCCESS;
+
+ // Transfer finished successfully. If there is another one to be
+ // performed in the current transaction, start it now.
+ // use a local variable to avoid using two volatile variables in one
+ // expression
+ uint8_t curr_transfer_idx = p_cb->current_transfer_idx;
+ ++curr_transfer_idx;
+ if (curr_transfer_idx < p_cb->p_current_transaction->number_of_transfers)
+ {
+ p_cb->current_transfer_idx = curr_transfer_idx;
+
+ result = start_transfer(((nrf_spi_mngr_t const *)p_context));
+
+ if (result == NRF_SUCCESS)
+ {
+ // The current transaction is running and its next transfer
+ // has been successfully started. There is nothing more to do.
+ return;
+ }
+ // if the next transfer could not be started due to some error
+ // we finish the transaction with this error code as the result
+ }
+ }
+ else
+ {
+ result = NRF_ERROR_INTERNAL;
+ }
+
+ // The current transaction has been completed or interrupted by some error.
+ // Notify the user and start next one (if there is any).
+ transaction_end_signal(((nrf_spi_mngr_t const *)p_context), result);
+ // we switch transactions here ('p_nrf_spi_mngr->p_current_transaction' is set
+ // to NULL only if there is nothing more to do) in order to not generate
+ // spurious idle status (even for a moment)
+ start_pending_transaction(((nrf_spi_mngr_t const *)p_context), true);
+}
+
+
+ret_code_t nrf_spi_mngr_init(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_default_spi_config)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+ ASSERT(p_nrf_spi_mngr->p_queue != NULL);
+ ASSERT(p_nrf_spi_mngr->p_queue->size > 0);
+ ASSERT(p_default_spi_config != NULL);
+
+ ret_code_t err_code;
+
+ err_code = nrf_drv_spi_init(&p_nrf_spi_mngr->spi,
+ p_default_spi_config,
+ spi_event_handler,
+ (void *)p_nrf_spi_mngr);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb;
+
+ p_cb->p_current_transaction = NULL;
+ p_cb->default_configuration = *p_default_spi_config;
+ p_cb->p_current_configuration = &p_cb->default_configuration;
+ }
+
+ return err_code;
+}
+
+
+void nrf_spi_mngr_uninit(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ nrf_drv_spi_uninit(&p_nrf_spi_mngr->spi);
+
+ p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction = NULL;
+}
+
+
+ret_code_t nrf_spi_mngr_schedule(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_spi_mngr_transaction_t const * p_transaction)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+ ASSERT(p_transaction != NULL);
+ ASSERT(p_transaction->p_transfers != NULL);
+ ASSERT(p_transaction->number_of_transfers != 0);
+
+ ret_code_t result = nrf_queue_push(p_nrf_spi_mngr->p_queue, (void *)(&p_transaction));
+ if (result == NRF_SUCCESS)
+ {
+ // New transaction has been successfully added to queue,
+ // so if we are currently idle it's time to start the job.
+ start_pending_transaction(p_nrf_spi_mngr, false);
+ }
+
+ return result;
+}
+
+
+static void spi_internal_transaction_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_spi_mngr_cb_data_t * p_cb_data = (nrf_spi_mngr_cb_data_t *)p_user_data;
+
+ p_cb_data->transaction_result = result;
+ p_cb_data->transaction_in_progress = false;
+}
+
+ret_code_t nrf_spi_mngr_perform(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_config,
+ nrf_spi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void))
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+ ASSERT(p_transfers != NULL);
+ ASSERT(number_of_transfers != 0);
+
+ nrf_spi_mngr_cb_data_t cb_data =
+ {
+ .transaction_in_progress = true
+ };
+
+ nrf_spi_mngr_transaction_t internal_transaction =
+ {
+ .begin_callback = NULL,
+ .end_callback = spi_internal_transaction_cb,
+ .p_user_data = (void *)&cb_data,
+ .p_transfers = p_transfers,
+ .number_of_transfers = number_of_transfers,
+ .p_required_spi_cfg = p_config
+ };
+
+ ret_code_t result = nrf_spi_mngr_schedule(p_nrf_spi_mngr, &internal_transaction);
+ VERIFY_SUCCESS(result);
+
+ while (cb_data.transaction_in_progress)
+ {
+ if (user_function)
+ {
+ user_function();
+ }
+ }
+
+ return cb_data.transaction_result;
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_SPI_MNGR)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h
new file mode 100644
index 0000000..434c950
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h
@@ -0,0 +1,310 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_SPI_MNGR_H__
+#define NRF_SPI_MNGR_H__
+
+#include <stdint.h>
+#include "nrf_drv_spi.h"
+#include "sdk_errors.h"
+#include "nrf_queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*lint -save -e491*/
+#ifndef NRF_SPI_MNGR_BUFFERS_IN_RAM
+ #define NRF_SPI_MNGR_BUFFERS_IN_RAM defined(SPIM_PRESENT)
+#endif
+
+#if NRF_SPI_MNGR_BUFFERS_IN_RAM
+ #define NRF_SPI_MNGR_BUFFER_LOC_IND
+#else
+ #define NRF_SPI_MNGR_BUFFER_LOC_IND const
+#endif
+/*lint -restore*/
+
+/**
+ * @defgroup nrf_spi_mngr SPI transaction manager
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for scheduling SPI transactions.
+ */
+
+
+/**
+ * @brief Macro for creating a simple SPI transfer.
+ *
+ * @param[in] _p_tx_data Pointer to the data to be sent.
+ * @param[in] _tx_length Number of bytes to send.
+ * @param[in] _p_rx_data Pointer to a buffer for received data.
+ * @param[in] _rx_length Number of bytes to receive.
+ */
+#define NRF_SPI_MNGR_TRANSFER(_p_tx_data, _tx_length, _p_rx_data, _rx_length) \
+{ \
+ .p_tx_data = (uint8_t const *)_p_tx_data, \
+ .tx_length = (uint8_t) _tx_length, \
+ .p_rx_data = (uint8_t *) _p_rx_data, \
+ .rx_length = (uint8_t) _rx_length, \
+}
+
+
+/**
+ * @brief SPI transaction end callback prototype.
+ *
+ * @param result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_user_data Pointer to user data defined in transaction
+ * descriptor.
+ */
+typedef void (* nrf_spi_mngr_callback_end_t)(ret_code_t result, void * p_user_data);
+
+/**
+ * @brief SPI transaction begin callback prototype.
+ *
+ * @param[in] p_user_data Pointer to user data defined in transaction
+ * descriptor.
+ */
+typedef void (* nrf_spi_mngr_callback_begin_t)(void * p_user_data);
+
+
+/**
+ * @brief SPI transfer descriptor.
+ */
+typedef struct
+{
+ uint8_t const * p_tx_data; ///< Pointer to the data to be sent.
+ uint8_t tx_length; ///< Number of bytes to send.
+ uint8_t * p_rx_data; ///< Pointer to a buffer for received data.
+ uint8_t rx_length; ///< Number of bytes to receive.
+} nrf_spi_mngr_transfer_t;
+
+
+/**
+ * @brief SPI transaction descriptor.
+ */
+typedef struct
+{
+ nrf_spi_mngr_callback_begin_t begin_callback;
+ ///< User-specified function to be called before the transaction is started.
+
+ nrf_spi_mngr_callback_end_t end_callback;
+ ///< User-specified function to be called after the transaction is finished.
+
+ void * p_user_data;
+ ///< Pointer to user data to be passed to the end_callback.
+
+ nrf_spi_mngr_transfer_t const * p_transfers;
+ ///< Pointer to the array of transfers that make up the transaction.
+
+ uint8_t number_of_transfers;
+ ///< Number of transfers that make up the transaction.
+
+ nrf_drv_spi_config_t const * p_required_spi_cfg;
+ ///< Pointer to instance hardware configuration.
+} nrf_spi_mngr_transaction_t;
+
+
+/**
+ * @brief SPI instance control block.
+ */
+typedef struct
+{
+ nrf_spi_mngr_transaction_t const * volatile p_current_transaction;
+ ///< Currently realized transaction.
+
+ nrf_drv_spi_config_t default_configuration;
+ ///< Default hardware configuration.
+
+ nrf_drv_spi_config_t const * p_current_configuration;
+ ///< Pointer to current hardware configuration.
+
+ uint8_t volatile current_transfer_idx;
+ ///< Index of currently performed transfer (within current transaction).
+} nrf_spi_mngr_cb_t;
+
+
+/**
+ * @brief SPI transaction manager instance.
+ */
+typedef struct
+{
+ nrf_spi_mngr_cb_t * p_nrf_spi_mngr_cb;
+ ///< Control block of instance.
+
+ nrf_queue_t const * p_queue;
+ ///< Transaction queue.
+
+ nrf_drv_spi_t spi;
+ ///< Pointer to SPI master driver instance.
+} nrf_spi_mngr_t;
+
+
+/**
+ * @brief Macro for simplifying the defining of an SPI transaction manager
+ * instance.
+ *
+ * This macro allocates a static buffer for the transaction queue.
+ * Therefore, it should be used in only one place in the code for a given
+ * instance.
+ *
+ * @note The queue size is the maximum number of pending transactions
+ * not counting the one that is currently realized. This means that
+ * for an empty queue with size of for example 4 elements, it is
+ * possible to schedule up to 5 transactions.
+ *
+ * @param[in] _nrf_spi_mngr_name Name of instance to be created.
+ * @param[in] _queue_size Size of the transaction queue (maximum number
+ * of pending transactions).
+ * @param[in] _spi_idx Index of hardware SPI instance to be used.
+ */
+#define NRF_SPI_MNGR_DEF(_nrf_spi_mngr_name, _queue_size, _spi_idx) \
+ NRF_QUEUE_DEF(nrf_spi_mngr_transaction_t const *, \
+ _nrf_spi_mngr_name##_queue, \
+ (_queue_size), \
+ NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static nrf_spi_mngr_cb_t CONCAT_2(_nrf_spi_mngr_name, _cb); \
+ static const nrf_spi_mngr_t _nrf_spi_mngr_name = \
+ { \
+ .p_nrf_spi_mngr_cb = &CONCAT_2(_nrf_spi_mngr_name, _cb), \
+ .p_queue = &_nrf_spi_mngr_name##_queue, \
+ .spi = NRF_DRV_SPI_INSTANCE(_spi_idx) \
+ }
+
+
+ /**
+ * @brief Function for initializing an SPI transaction manager instance.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the instance to be initialized.
+ * @param[in] p_default_spi_config Pointer to the SPI driver configuration. This configuration
+ * will be used whenever the scheduled transaction will have
+ * p_spi_config set to NULL value.
+ *
+ * @return Values returned by the @ref nrf_drv_spi_init function.
+ */
+ret_code_t nrf_spi_mngr_init(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_default_spi_config);
+
+
+/**
+ * @brief Function for uninitializing an SPI transaction manager instance.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the instance to be uninitialized.
+ */
+void nrf_spi_mngr_uninit(nrf_spi_mngr_t const * p_nrf_spi_mngr);
+
+
+/**
+ * @brief Function for scheduling an SPI transaction.
+ *
+ * The transaction is enqueued and started as soon as the SPI bus is
+ * available, thus when all previously scheduled transactions have been
+ * finished (possibly immediately).
+ *
+ * @note If @ref nrf_spi_mngr_transaction_t::p_required_spi_cfg
+ * is set to a non-NULL value the module will compare it with
+ * @ref nrf_spi_mngr_cb_t::p_current_configuration and reinitialize hardware
+ * SPI instance with new parameters if any differences are found.
+ * If @ref nrf_spi_mngr_transaction_t::p_required_spi_cfg is set to NULL then
+ * it will treat it as it would be set to @ref nrf_spi_mngr_cb_t::default_configuration.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance.
+ * @param[in] p_transaction Pointer to the descriptor of the transaction to be
+ * scheduled.
+ *
+ * @retval NRF_SUCCESS If the transaction has been successfully scheduled.
+ * @retval NRF_ERROR_NO_MEM If the queue is full (Only if queue in
+ * @ref NRF_QUEUE_MODE_NO_OVERFLOW).
+ */
+ret_code_t nrf_spi_mngr_schedule(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_spi_mngr_transaction_t const * p_transaction);
+
+
+/**
+ * @brief Function for scheduling a transaction and waiting until it is finished.
+ *
+ * This function schedules a transaction that consists of one or more transfers
+ * and waits until it is finished.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance.
+ * @param[in] p_config Required SPI configuration.
+ * @param[in] p_transfers Pointer to an array of transfers to be performed.
+ * @param number_of_transfers Number of transfers to be performed.
+ * @param user_function User-specified function to be called while
+ * waiting. NULL if such functionality
+ * is not needed.
+ *
+ * @retval NRF_SUCCESS If the transfers have been successfully realized.
+ * @retval NRF_ERROR_BUSY If some transfers are already being performed.
+ * @retval - Other error codes mean that the transaction has failed
+ * with the error reported by @ref nrf_drv_spi_transfer().
+ */
+ret_code_t nrf_spi_mngr_perform(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_config,
+ nrf_spi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void));
+
+
+/**
+ * @brief Function for getting the current state of an SPI transaction manager
+ * instance.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance.
+ *
+ * @retval true If all scheduled transactions have been finished.
+ * @retval false Otherwise.
+ */
+__STATIC_INLINE bool nrf_spi_mngr_is_idle(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ return (p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction == NULL);
+}
+
+/**
+ *@}
+ **/
+//typedef int p_current_transaction;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SPI_MNGR_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h
new file mode 100644
index 0000000..cf7902a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup nrf_stack_info Stack info functions and definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Functions and definitions used to obtain information about the state of the stack.
+ */
+
+#ifndef NRF_STACK_INFO_H__
+#define NRF_STACK_INFO_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Top (highest) stack address.
+ */
+#define NRF_STACK_INFO_TOP ((uint32_t)STACK_TOP)
+
+
+/**
+ * @brief Base (lowest) stack address.
+ */
+#define NRF_STACK_INFO_BASE ((uint32_t)STACK_BASE)
+
+
+/**
+ * @brief Function to get the current stack pointer value.
+ *
+ * @return Current stack pointer value.
+ */
+#define NRF_STACK_INFO_GET_SP() ((uint32_t)GET_SP())
+
+
+__STATIC_INLINE size_t nrf_stack_info_get_available(void);
+__STATIC_INLINE size_t nrf_stack_info_get_depth(void);
+__STATIC_INLINE bool nrf_stack_info_overflowed(void);
+__STATIC_INLINE bool nrf_stack_info_is_on_stack(void const * const p_address);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ * @brief Calculate the available (free) space on the stack.
+ *
+ * @return Number of available bytes on the stack.
+ */
+ __STATIC_INLINE size_t nrf_stack_info_get_available(void)
+{
+ uint32_t sp = NRF_STACK_INFO_GET_SP();
+ if (sp > NRF_STACK_INFO_BASE)
+ {
+ return (size_t)(sp - NRF_STACK_INFO_BASE);
+ }
+
+ // Stack overflow
+ return 0;
+}
+
+
+/**
+ * @brief Calculate the current stack depth (occupied space).
+ *
+ * @return Current stack depth in bytes.
+ */
+__STATIC_INLINE size_t nrf_stack_info_get_depth(void)
+{
+ return (size_t)(NRF_STACK_INFO_TOP - NRF_STACK_INFO_GET_SP());
+}
+
+
+/**
+ * @brief Function for checking if the stack is currently overflowed.
+ *
+ * @details This function checks if the stack is currently in an overflowed by comparing the stack
+ * pointer with the stack base address. Intended to be used to be used to ease debugging.
+ *
+ * @return true if stack is currently overflowed, false otherwise.
+ */
+ __STATIC_INLINE bool nrf_stack_info_overflowed(void)
+ {
+ if (NRF_STACK_INFO_GET_SP() < NRF_STACK_INFO_BASE)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+/**
+ * @brief Function for checking if provided address is located in stack space.
+ *
+ * @param[in] p_address Address to be checked.
+ *
+ * @return true if address is in stack space, false otherwise.
+ */
+__STATIC_INLINE bool nrf_stack_info_is_on_stack(void const * const p_address)
+{
+ if (((uint32_t)p_address >= NRF_STACK_INFO_BASE) && ((uint32_t)p_address < NRF_STACK_INFO_TOP))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_STACK_INFO_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c
new file mode 100644
index 0000000..4824b6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2011 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_STRERROR)
+#include "nrf_strerror.h"
+
+/**
+ * @brief Macro for adding an entity to the description array.
+ *
+ * Macro that helps to create a single entity in the description array.
+ */
+#define NRF_STRERROR_ENTITY(mnemonic) {.code = mnemonic, .name = #mnemonic}
+
+/**
+ * @brief Array entity element that describes an error.
+ */
+typedef struct
+{
+ ret_code_t code; /**< Error code. */
+ char const * name; /**< Descriptive name (the same as the internal error mnemonic). */
+}nrf_strerror_desc_t;
+
+/**
+ * @brief Unknown error code.
+ *
+ * The constant string used by @ref nrf_strerror_get when the error description was not found.
+ */
+static char const m_unknown_str[] = "Unknown error code";
+
+/**
+ * @brief Array with error codes.
+ *
+ * Array that describes error codes.
+ *
+ * @note It is required for this array to have error codes placed in ascending order.
+ * This condition is checked in automatic unit test before the release.
+ */
+static nrf_strerror_desc_t const nrf_strerror_array[] =
+{
+ NRF_STRERROR_ENTITY(NRF_SUCCESS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_SVC_HANDLER_MISSING),
+ NRF_STRERROR_ENTITY(NRF_ERROR_SOFTDEVICE_NOT_ENABLED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INTERNAL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NO_MEM),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NOT_FOUND),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NOT_SUPPORTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_PARAM),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_STATE),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_LENGTH),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_FLAGS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_DATA),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DATA_SIZE),
+ NRF_STRERROR_ENTITY(NRF_ERROR_TIMEOUT),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NULL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_FORBIDDEN),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_ADDR),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BUSY),
+#ifdef NRF_ERROR_CONN_COUNT
+ NRF_STRERROR_ENTITY(NRF_ERROR_CONN_COUNT),
+#endif
+#ifdef NRF_ERROR_RESOURCES
+ NRF_STRERROR_ENTITY(NRF_ERROR_RESOURCES),
+#endif
+
+ /* SDK Common errors */
+ NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_NOT_INITIALIZED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_INIT_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_LOCK_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_UNLOCK_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_COND_INIT_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_ALREADY_INITIALIZED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_STORAGE_FULL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_API_NOT_IMPLEMENTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_FEATURE_NOT_ENABLED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_IO_PENDING),
+
+ /* TWI error codes */
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_OVERRUN),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_ANACK),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_DNACK),
+
+ /* IPSP error codes */
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_PEER_REJECTED)
+};
+
+
+char const * nrf_strerror_get(ret_code_t code)
+{
+ char const * p_ret = nrf_strerror_find(code);
+ return (p_ret == NULL) ? m_unknown_str : p_ret;
+}
+
+char const * nrf_strerror_find(ret_code_t code)
+{
+ nrf_strerror_desc_t const * p_start;
+ nrf_strerror_desc_t const * p_end;
+ p_start = nrf_strerror_array;
+ p_end = nrf_strerror_array + ARRAY_SIZE(nrf_strerror_array);
+
+ while (p_start < p_end)
+ {
+ nrf_strerror_desc_t const * p_mid = p_start + ((p_end - p_start) / 2);
+ ret_code_t mid_c = p_mid->code;
+ if (mid_c > code)
+ {
+ p_end = p_mid;
+ }
+ else if (mid_c < code)
+ {
+ p_start = p_mid + 1;
+ }
+ else
+ {
+ return p_mid->name;
+ }
+ }
+ return NULL;
+}
+
+#endif /* NRF_STRERROR enabled */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h
new file mode 100644
index 0000000..1a6542b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @defgroup nrf_strerror Error code to string converter
+ * @ingroup app_common
+ *
+ * @brief Module for converting error code into a printable string.
+ * @{
+ */
+#ifndef NRF_STRERROR_H__
+#define NRF_STRERROR_H__
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for getting a printable error string.
+ *
+ * @param code Error code to convert.
+ *
+ * @note This function cannot fail.
+ * For the function that may fail with error translation, see @ref nrf_strerror_find.
+ *
+ * @return Pointer to the printable string.
+ * If the string is not found,
+ * it returns a simple string that says that the error is unknown.
+ */
+char const * nrf_strerror_get(ret_code_t code);
+
+/**
+ * @brief Function for finding a printable error string.
+ *
+ * This function gets the error string in the same way as @ref nrf_strerror_get,
+ * but if the string is not found, it returns NULL.
+ *
+ * @param code Error code to convert.
+ * @return Pointer to the printable string.
+ * If the string is not found, NULL is returned.
+ */
+char const * nrf_strerror_find(ret_code_t code);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_STRERROR_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h
new file mode 100644
index 0000000..df03b4d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup sdk_nrf_svc_function Supervisor function
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Supervisor functions.
+ */
+
+#ifndef NRF_SVC_FUNCTION_H__
+#define NRF_SVC_FUNCTION_H__
+
+#include <stdint.h>
+#include "nrf_section.h"
+#include "app_util.h"
+#include "nrf_svci.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @brief Function to be called from an SVC handler.
+ *
+ * @warning This function prototype has no arguments. It will be cast to a function prototype
+ * that has 0 to 4 arguments. 4 arguments is the highest number of allowed arguments in
+ * a Supervisor call.
+ *
+ * @warning The nrf_svc_func_t function prototype should not have void as parameter list as there
+ * will be 0 to 4 arguments after casting.
+ */
+typedef uint32_t (*nrf_svc_func_t)();
+
+/** @brief Type holding the SVC number, SVCI number, and the pointer to the corresponding handler
+ * function.
+ *
+ * @note The function that is pointed to must not change version.
+ */
+typedef struct
+{
+ uint32_t svc_num; /**< Supervisor call number (actually 8-bit, padded for alignment). */
+ uint32_t svci_num; /**< Supervisor call indirect number. */
+ nrf_svc_func_t func_ptr;
+} nrf_svc_func_reg_t;
+
+
+// Verify that the size of nrf_svc_func_t is aligned to make sure it can be used in nrf_section.
+STATIC_ASSERT(sizeof(nrf_svc_func_reg_t) % 4 == 0);
+
+
+/** @brief Macro for registering a structure holding SVC number and SVC handler
+ * function pointer.
+ *
+ * @details This macro places a variable in a section named "svc_data" that
+ * the SVC handler uses during regular operation.
+ *
+ * @note This macro must be invoked from a source file. There should only be one
+ * registration by a given SVC number. SVC number 0 (zero) is invalid input
+ * and will cause a compile time assertion.
+ *
+ * @param[in] name Name of the structure. Logically accessible from the source file.
+ * @param[in] svc_number SVC number to register.
+ * @param[in] func Function to call for a given SVC number.
+ *
+ * @retval Variable registration in @ref lib_section_vars named svc_data.
+ */
+#define NRF_SVC_FUNCTION_REGISTER(svc_number, name, func) \
+STATIC_ASSERT(svc_number != 0); \
+NRF_SECTION_ITEM_REGISTER(svc_data, nrf_svc_func_reg_t const name) = \
+{ \
+ .svc_num = svc_number, \
+ .svci_num = NRF_SVCI_SVC_NUM_INVALID, \
+ .func_ptr = (nrf_svc_func_t)func \
+}
+
+
+/** @brief Macro for registering a structure holding SVC number, SVCI number, and SVCI handler
+ * function pointer.
+ *
+ * @details This macro places a variable in a section named "svc_data" that
+ * the SVC handler uses during regular operation.
+ *
+ * @note This macro must be invoked from a source file. There should only be one registration
+ * for a given SVC indirect number.
+ *
+ * @param[in] name Name of the structure. Logically accessible from the source file.
+ * @param[in] svci_number SVC indirect number to register.
+ * @param[in] func Function to call for a given SVC indirect number.
+ *
+ * @retval Variable registration in @ref lib_section_vars named svc_data.
+ */
+#define NRF_SVCI_FUNCTION_REGISTER(svci_number, name, func) \
+NRF_SECTION_ITEM_REGISTER(svc_data, nrf_svc_func_reg_t const name) = \
+{ \
+ .svc_num = NRF_SVCI_SVC_NUM, \
+ .svci_num = svci_number, \
+ .func_ptr = (nrf_svc_func_t)func \
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SVC_FUNCTION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c
new file mode 100644
index 0000000..2c7aaca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include "nrf_svc_function.h"
+#include "nrf_error.h"
+
+#include "nrf_log.h"
+
+//lint -esym(526, svc_dataBase) -esym(526, svc_dataLimit)
+NRF_SECTION_DEF(svc_data, const nrf_svc_func_t);
+#define SVC_DATA_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(svc_data, nrf_svc_func_reg_t, (i))
+#define SVC_DATA_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(svc_data, nrf_svc_func_reg_t)
+
+
+#ifdef __GNUC__
+// Prevent GCC from removing this function (called from assembly branch)
+void nrf_svc_handler_c(uint32_t* p_svc_args) __attribute__((used));
+#endif
+
+
+
+/**@brief Function for handling second stage of Supervisor Calls (SVC).
+*
+* @details The function will use loop through the registered svc functions stored
+* in the named section "svc_data" and will call the registered function
+* if the svn_num corresponds with the registration.
+*
+* @param[in] p_svc_args Argument list for the SVC.
+*
+* @return This function returns by updating p_svc_arsg[0]. This will be reported back to the caller of SVC
+* @ref NRF_ERROR_SVC_HANDLER_MISSING is returned if no SVC handler is implemented for the
+* provided svc_num.
+*/
+void nrf_svc_handler_c(uint32_t* p_svc_args)
+{
+ uint32_t const num_funcs = SVC_DATA_SECTION_ITEM_COUNT;
+ bool handled = false;
+ uint8_t const svc_num = ((uint8_t *)p_svc_args[6])[-2];
+ uint32_t svci_num = NRF_SVCI_SVC_NUM_INVALID;
+
+ if (svc_num == NRF_SVCI_SVC_NUM)
+ {
+ // load the stacked R12 as the svci_num
+ svci_num = p_svc_args[4];
+ }
+
+ for (uint32_t i = 0; i < num_funcs; i++)
+ {
+ nrf_svc_func_reg_t const * func_reg = SVC_DATA_SECTION_ITEM_GET(i);
+ if (func_reg->svc_num != svc_num)
+ {
+ continue;
+ }
+
+ if (svci_num != NRF_SVCI_SVC_NUM_INVALID && func_reg->svci_num != svci_num)
+ {
+ continue;
+ }
+
+ // Return value is placed in R0
+ p_svc_args[0] = func_reg->func_ptr(p_svc_args[0], p_svc_args[1], p_svc_args[2], p_svc_args[3]);
+ handled = true;
+ break;
+ }
+
+ if (handled == false)
+ {
+ // Return value is placed in R0
+ p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING;
+ }
+}
+
+/**@brief Function for handling the first stage of Supervisor Calls (SVC) in assembly.
+*
+* @details The function will use the link register (LR) to determine the stack (PSP or MSP) to be
+* used and then decode the SVC number afterwards. After decoding the SVC number,
+* @ref C_SVC_Handler is called for further processing of the SVC.
+*/
+#if defined ( __CC_ARM )
+__ASM void SVC_Handler(void)
+{
+ tst lr, #4 ; Test bit 2 of EXT_RETURN to see if MSP or PSP is used
+ ite eq ;
+ mrseq r0, MSP ; If equal, copy stack pointer from MSP
+ mrsne r0, PSP ; If not equal, copy stack pointer from PSP
+ B __cpp(nrf_svc_handler_c) ; Call C-implementation of handler. Exception stack frame in R0
+ ALIGN 4 ; Protect with alignment
+}
+#elif defined ( __GNUC__ )
+void __attribute__((naked)) SVC_Handler(void)
+{
+ __ASM volatile
+ (
+ "tst lr, #4\t\n" // Test bit 2 of EXT_RETURN to see if MSP or PSP is used
+ "ite eq\t\n" //
+ "mrseq r0, MSP\t\n" // Move MSP into R0.
+ "mrsne r0, PSP\t\n" // Move PSP into R0.
+ "b nrf_svc_handler_c\t\n" // Call C-implementation of handler. Exception stack frame in R0
+ ".align\t\n" // Protect with alignment
+ );
+}
+#elif defined ( __ICCARM__ )
+void SVC_Handler(void)
+{
+ __ASM volatile
+ (
+ "tst lr, #4\t\n" // Test bit in link register responsible for stack indication.
+ "ite eq\t\n" // Test bit 2 of EXT_RETURN to see if MSP or PSP is used
+ "mrseq r0, MSP\t\n" // Move MSP into R0.
+ "mrsne r0, PSP\t\n" // Move PSP into R0.
+ "b nrf_svc_handler_c\t\n" : // Call C-implementation of handler. Exception stack frame in R0
+ );
+}
+#else
+
+#error Compiler not supported.
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h
new file mode 100644
index 0000000..38d54e3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup sdk_nrf_svci Supervisor instructions with indirect number
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Supervisor instructions using indirect number.
+ */
+
+#ifndef NRF_SVCI_H__
+#define NRF_SVCI_H__
+
+#include "stdint.h"
+#include "compiler_abstraction.h"
+#include "app_util.h"
+
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_SVCI_SVC_NUM 0 /**< SVC number used for all SVCI functions. */
+#define NRF_SVCI_SVC_NUM_INVALID (0xFFFFFFFF) /**< Invalid SVCI number. */
+
+#ifdef __cplusplus
+ #define GCC_CAST_CPP (uint8_t)
+#else
+ #define GCC_CAST_CPP
+#endif
+
+#if (__LINT__ != 1)
+
+#if defined (__CC_ARM)
+
+ #define SVCI_DECL(svci_num, return_type, function_name, ...) \
+ return_type __svc_indirect(NRF_SVCI_SVC_NUM) \
+ svci_ ## function_name(uint32_t _svci_num, ##__VA_ARGS__);
+
+ #define SVCI_DECL_0(svci_num, return_type, function_name) \
+ return_type __svc_indirect(NRF_SVCI_SVC_NUM) \
+ svci_ ## function_name(uint32_t _svci_num);
+
+ #define SVCI_0(svci_num, return_type, function_name) \
+ SVCI_DECL_0(svci_num, return_type, function_name) \
+ static __INLINE return_type function_name(void) \
+ { \
+ return svci_ ## function_name(svci_num); \
+ }
+
+ #define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \
+ static __INLINE return_type function_name(p0t p0n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n); \
+ }
+
+ #define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n, p1n); \
+ }
+
+ #define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n, p1n, p2n); \
+ }
+
+ #define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n, p1n, p2n, p3n); \
+ }
+
+#else
+
+#if defined (__GNUC__)
+
+ #define SVCI_DECL_0(svci_num, return_type, function_name) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked, unused)) \
+ static return_type svci_ ## function_name(void) \
+ { \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM __volatile \
+ ( \
+ " ldr r12, =%0 \n" \
+ " svc %1 \n" \
+ " bx lr \n" \
+ " .ltorg" \
+ : /* output */ \
+ : /* input */ \
+ "X"(svci_num), \
+ "I"(GCC_CAST_CPP NRF_SVCI_SVC_NUM) \
+ : /* clobbers */ \
+ "r12" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+ #define SVCI_DECL(svci_num, return_type, function_name, ...) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked, unused)) \
+ static return_type svci_ ## function_name(__VA_ARGS__) \
+ { \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM __volatile \
+ ( \
+ " ldr.w r12, =%0 \n" \
+ " svc %1 \n" \
+ " bx lr \n" \
+ " .ltorg" \
+ : /* output */ \
+ : /* input */ \
+ "X"(svci_num), \
+ "I"(GCC_CAST_CPP NRF_SVCI_SVC_NUM) \
+ : /* clobbers */ \
+ "r12" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+
+ #define SVCI_DECL_0(svci_num, return_type, function_name) \
+ /* Suppress return value warning. */ \
+ _Pragma("diag_suppress=Pe940") \
+ static __root return_type svci_ ## function_name(void) \
+ { \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM volatile \
+ ( \
+ " mov r12, %0 \n" \
+ " svc %1 \n" \
+ : /*no output*/ \
+ : "r" (svci_num), "I" (NRF_SVCI_SVC_NUM) \
+ : \
+ ); \
+ }
+
+ #define SVCI_DECL(svci_num, return_type, function_name, ...) \
+ /* Suppress return value warning. */ \
+ _Pragma("diag_suppress=Pe940") \
+ static __root return_type svci_ ## function_name(__VA_ARGS__) \
+ { \
+ /* We stack r0-r3 as r0 is used to set high register (r12) \
+ This CODE MUST BE IN ITS OWN __ASM BLOCK! */ \
+ __ASM volatile ( "push {r0, r1, r2, r3}\n\t" ); \
+ /* Set R12 to the svc_number, this will use r0 as indirect \
+ * storage. Pop r0-r3 to reset value before SVCI. */ \
+ __ASM volatile \
+ ( \
+ " mov r12, %0 \n" \
+ " pop {r0, r1, r2, r3} \n" \
+ : /*no output */ \
+ : "r" (svci_num) \
+ : \
+ ); \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM volatile \
+ ( \
+ " svc %0 \n" \
+ " bx lr \n" \
+ : /*no output*/ \
+ : "I" (NRF_SVCI_SVC_NUM) \
+ : \
+ ); \
+ }
+#else // Not defined (__ICCARM__) or defined (__GNUC__)
+
+ #error Unsupported compiler for SVCI interface
+
+#endif // Not defined (__ICCARM__) or defined (__GNUC__)
+
+ #define SVCI_0(svci_num, return_type, function_name) \
+ SVCI_DECL_0(svci_num, return_type, function_name) \
+ static __INLINE return_type function_name(void) \
+ { \
+ return svci_ ## function_name(); \
+ }
+
+ #define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \
+ static __INLINE return_type function_name(p0t p0n) \
+ { \
+ return svci_ ## function_name(p0n); \
+ }
+
+ #define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n) \
+ { \
+ return svci_ ## function_name(p0n, p1n); \
+ }
+
+ #define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) \
+ { \
+ return svci_ ## function_name(p0n, p1n, p2n); \
+ }
+
+ #define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ { \
+ return svci_ ## function_name(p0n, p1n, p2n, p3n); \
+ }
+
+#endif // Not __CC_ARM
+
+#define VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
+#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 4, 4, 3, 3, 2, 2, 1, 1, 0)
+
+#ifdef SVCALL_INDIRECT_AS_NORMAL_FUNCTION
+
+#define SVCI(svci_num, return_type, function_name, ...) \
+ return_type function_name(##__VA_ARGS__)
+
+#else
+
+
+#define SVCI_IMPLI(count, svci_num, return_type, function_name, ...) \
+ SVCI##_##count (svci_num, return_type, function_name, ##__VA_ARGS__)
+
+#define SVCI_IMPL(count, svci_num, return_type, function_name, ...) \
+ SVCI_IMPLI(count, svci_num, return_type, function_name, ##__VA_ARGS__)
+
+#define SVCI(svci_num, return_type, function_name, ...) \
+ SVCI_IMPL(VA_NARGS(__VA_ARGS__), svci_num, return_type, function_name, ##__VA_ARGS__)
+
+
+#endif // SVCALL_INDIRECT_AS_NORMAL_FUNCTION
+
+#else // (__LINT__ == 1)
+ #define SVCI(svci_num, return_type, function_name, ...)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif // NRF_SVCI_H__
+
+
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h
new file mode 100644
index 0000000..ca1f85a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup sdk_nrf_svci_async_function Asynchronous Supervisor function interface
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Asynchronous Supervisor interface functions.
+ */
+
+#ifndef NRF_SVC_ASYNC_FUNCTION_H__
+#define NRF_SVC_ASYNC_FUNCTION_H__
+
+#include "nrf_svci.h"
+#include "nrf_svci_async_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for creating type definition for SVCI interface init function.
+ *
+ * @warning Do not call this macro directly! Use @ref NRF_SVCI_ASYNC_FUNC_DECLARE instead.
+ *
+ * @param[in] name Name of async request function. Will be appended with _async_fn_t.
+ * @param[in] param_type Parameter type.
+ * @param[in] state_type State type.
+ *
+ * @retval Type definition a named SVCI async init function.
+ */
+#define NRF_SVCI_ACYNC_FUNC_TYPEDEF(name, param_type, state_type) \
+typedef uint32_t (* name ## _async_fn_t)(param_type * p_param, state_type * p_state)
+
+
+/**@brief Macro for creating type definition for SVCI interface event function.
+ *
+ * @warning Do not call this macro directly! Use @ref NRF_SVCI_ASYNC_FUNC_DECLARE instead.
+ *
+ * @details Calling this function with sys-events will report @ref NRF_ERROR_BUSY until
+ * the asynchronous calls is finished, at which time it will report either
+ * NRF_SUCCESS or any another error-message.
+ *
+ * @param[in] name Name of the event function. Will be appended with _event_fn_t
+ * @param[in] state_type Type parameter for the state.
+ *
+ * @retval Type definition for a named SVCI async event function.
+ */
+#define NRF_SVCI_ASYNC_EVENT_FUNC_TYPEDEF(name, state_type) \
+typedef uint32_t (* name ## _event_fn_t)(uint32_t sys_evt, state_type * p_state)
+
+
+/**@brief Macro for creating a declaration of a named async function for the SVCI interface.
+ *
+ * @details The async interface provides a method to call into a external application
+ * through the SVCI interface without relying on allocated or reserved memory inside the
+ * external application.
+ *
+ * This macro declares variables and function types in use by the async SVCI interface.
+ *
+ * @note This is intended to be invoked in a header file shared by both the
+ * caller and the recipient (handler).
+ *
+ * @param[in] svci_num SVC indirect number.
+ * @param[in] name Name of the async function.
+ * @param[in] param_type Type of the param used for the async interface.
+ * @param[in] state_type Type of the state used for the async interface.
+ *
+ * @retval A type definition of NAME_svc_async_t to be used for async access
+ * through the SVCI interface.
+ */
+#define NRF_SVCI_ASYNC_FUNC_DECLARE(svci_num, \
+ name, \
+ param_type, \
+ state_type) \
+/*lint --e{19} */ \
+NRF_SVCI_ACYNC_FUNC_TYPEDEF(name, param_type, state_type); \
+NRF_SVCI_ASYNC_EVENT_FUNC_TYPEDEF(name, state_type); \
+ \
+typedef struct \
+{ \
+ name ## _async_fn_t async_func; \
+ name ## _event_fn_t sys_evt_handler; \
+ state_type state; \
+} name ## _svci_async_t;
+
+
+
+//lint -save --e{10, 19, 40, 102} -esym(526, *_init) -esym(628, *_init)
+
+/**@brief Macro for defining a named SVCI async interface.
+ *
+ * @details The async interface provides a method to call into an external application
+ * through the SVCI interface without relying on allocated or reserved memory inside the
+ * external application.
+ *
+ * Running this macro creates a defintion of the structure that holds the
+ * information about the async function, the event handler, and the state.
+ *
+ * Running this macro also defines convenience functions to the SVCI interface.
+ *
+ * The available functions are:
+ * -NAME_init - Function to call to set up the async SVCI interface.
+ * -NAME - Function to call the async SVCI interface.
+ * -NAME_on_sys_event - Function to report sys events to the async
+ * SVCI interface.
+ * -NAME_is_initialized - Function to check if the async SVCI interface is
+ * initialized and ready to use.
+ *
+ * @note Invoking this macro is only possible in a source file as the macro creates
+ * a static variable for the async interface as well as static functions to call
+ * into the async interface.
+ *
+ * @param[in] svci_num SVC indirect number.
+ * @param[in] name Name of the async function.
+ * @param[in] param_type Type of the param used for the async interface.
+ *
+ * @retval Instance of the async SVCI interface and convenience functions for using it.
+ */
+#define NRF_SVCI_ASYNC_FUNC_DEFINE(svci_num, name, param_type) \
+ \
+SVCI(svci_num, uint32_t, name ## _svci_async_init, name ## _svci_async_t *, p_async); \
+static name ## _svci_async_t name ## _svci_async_def = {0}; \
+ \
+static __INLINE uint32_t name ## _init (void) \
+{ \
+ return name ## _svci_async_init(&name ## _svci_async_def); \
+} \
+ \
+static __INLINE uint32_t name(param_type * p_param) \
+{ \
+ return name ## _svci_async_def.async_func(p_param, &name ## _svci_async_def.state); \
+} \
+ \
+static __INLINE uint32_t name ## _on_sys_evt(uint32_t sys_evt) \
+{ \
+ return name ## _svci_async_def.sys_evt_handler(sys_evt, &name ## _svci_async_def.state); \
+} \
+ \
+static __INLINE uint32_t name ## _is_initialized(void) \
+{ \
+ return (name ## _svci_async_def.async_func != NULL && \
+ name ## _svci_async_def.sys_evt_handler != NULL ); \
+}
+
+//lint -restore
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SVC_ASYNC_FUNCTION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h
new file mode 100644
index 0000000..a1d2270
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup sdk_nrf_svci_async_handler Asynchronous Supervisor handler functions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Asynchronous Supervisor interface handler functions.
+ */
+
+#ifndef NRF_SVCI_ASYNC_HANDLER_H__
+#define NRF_SVCI_ASYNC_HANDLER_H__
+
+#include "nrf_svc_function.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for creating a registration for an async handler for the SVCI interface
+ *
+ * @details Calling this macro will register a SVCI function handler using @ref
+ * NRF_SVCI_FUNCTION_REGISTER
+ *
+ * @note This macro must be invoked from a source file as it declares static functions
+ * to be implemented and because it creates a @ref lib_section_vars registration to
+ * SVCI interface which is intended to be unique.
+ *
+ * @param[in] svci_num SVC indirect number.
+ * @param[in] name Name of the async function.
+ * @param[in] param_type Type of the param to send when running the async interface.
+ * @param[in] state_type Type of the state to be called together with sys_event.
+ *
+ * @retval Static declarations to handler functions to be implemented in the form NAME_handler
+ * NAME_on_call, and NAME_on_sys_event.
+ */
+#define NRF_SVCI_ASYNC_HANDLER_CREATE(svci_num, \
+ name, \
+ param_type, \
+ state_type) \
+ \
+static uint32_t name ## _handler(name ## _svci_async_t * p_async); \
+static uint32_t name ## _on_call(param_type * p_param, state_type * p_state); \
+static uint32_t name ## _on_sys_evt(uint32_t sys_event, state_type * p_state); \
+ \
+NRF_SVCI_FUNCTION_REGISTER(svci_num, name ## _var, name ## _handler)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SVCI_ASYNC_HANDLER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c
new file mode 100644
index 0000000..0df49b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c
@@ -0,0 +1,1075 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_TIMER)
+#include "app_timer.h"
+#include <stdlib.h>
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+#include "nrf_delay.h"
+#include "app_util_platform.h"
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+#include "app_scheduler.h"
+#endif
+
+#define RTC1_IRQ_PRI APP_TIMER_CONFIG_IRQ_PRIORITY /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */
+#define SWI_IRQ_PRI APP_TIMER_CONFIG_IRQ_PRIORITY /**< Priority of the SWI interrupt (used for updating the timer list). */
+
+// The current design assumes that both interrupt handlers run at the same interrupt level.
+// If this is to be changed, protection must be added to prevent them from interrupting each other
+// (e.g. by using guard/trigger flags).
+STATIC_ASSERT(RTC1_IRQ_PRI == SWI_IRQ_PRI);
+
+#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */
+
+#define RTC_COMPARE_OFFSET_MIN 3 /**< Minimum offset between the current RTC counter value and the Capture Compare register. Although the nRF51 Series User Specification recommends this value to be 2, we use 3 to be safer.*/
+
+#define MAX_RTC_TASKS_DELAY 47 /**< Maximum delay until an RTC task is executed. */
+
+#ifdef EGU_PRESENT
+#define SWI_PART(_id) CONCAT_2(SWI,_id)
+#define EGU_PART(_id) CONCAT_2(_EGU,_id)
+#define SWI_IRQ_n(_id) CONCAT_3(SWI_PART(_id), EGU_PART(_id),_IRQn)
+#define SWI_IRQ_Handler_n(_id) CONCAT_3(SWI_PART(_id), EGU_PART(_id),_IRQHandler)
+#else //EGU_PRESENT
+#define SWI_IRQ_n(_id) CONCAT_3(SWI,_id,_IRQn)
+#define SWI_IRQ_Handler_n(_id) CONCAT_3(SWI,_id,_IRQHandler)
+#endif
+
+#define SWI_IRQn SWI_IRQ_n(APP_TIMER_CONFIG_SWI_NUMBER)
+#define SWI_IRQHandler SWI_IRQ_Handler_n(APP_TIMER_CONFIG_SWI_NUMBER)
+
+
+#define MODULE_INITIALIZED (m_op_queue.size != 0) /**< Macro designating whether the module has been initialized properly. */
+
+/**@brief Timer node type. The nodes will be used form a linked list of running timers. */
+typedef struct
+{
+ uint32_t ticks_to_expire; /**< Number of ticks from previous timer interrupt to timer expiry. */
+ uint32_t ticks_at_start; /**< Current RTC counter value when the timer was started. */
+ uint32_t ticks_first_interval; /**< Number of ticks in the first timer interval. */
+ uint32_t ticks_periodic_interval; /**< Timer period (for repeating timers). */
+ bool is_running; /**< True if timer is running, False otherwise. */
+ app_timer_mode_t mode; /**< Timer mode. */
+ app_timer_timeout_handler_t p_timeout_handler; /**< Pointer to function to be executed when the timer expires. */
+ void * p_context; /**< General purpose pointer. Will be passed to the timeout handler when the timer expires. */
+ void * next; /**< Pointer to the next node. */
+} timer_node_t;
+
+STATIC_ASSERT(sizeof(timer_node_t) == APP_TIMER_NODE_SIZE);
+
+/**@brief Set of available timer operation types. */
+typedef enum
+{
+ TIMER_USER_OP_TYPE_NONE, /**< Invalid timer operation type. */
+ TIMER_USER_OP_TYPE_START, /**< Timer operation type Start. */
+ TIMER_USER_OP_TYPE_STOP, /**< Timer operation type Stop. */
+ TIMER_USER_OP_TYPE_STOP_ALL /**< Timer operation type Stop All. */
+} timer_user_op_type_t;
+
+/**@brief Structure describing a timer start operation. */
+typedef struct
+{
+ uint32_t ticks_at_start; /**< Current RTC counter value when the timer was started. */
+ uint32_t ticks_first_interval; /**< Number of ticks in the first timer interval. */
+ uint32_t ticks_periodic_interval; /**< Timer period (for repeating timers). */
+ void * p_context; /**< General purpose pointer. Will be passed to the timeout handler when the timer expires. */
+} timer_user_op_start_t;
+
+/**@brief Structure describing a timer operation. */
+typedef struct
+{
+ timer_user_op_type_t op_type; /**< Id of timer on which the operation is to be performed. */
+ timer_node_t * p_node;
+ union
+ {
+ timer_user_op_start_t start; /**< Structure describing a timer start operation. */
+ } params;
+} timer_user_op_t;
+
+/**@brief Structure describing a timer operations queue.
+ *
+ * @details This queue will hold timer operations issued by the application
+ * until the timer interrupt handler processes these operations.
+ */
+typedef struct
+{
+ uint8_t first; /**< Index of first entry to have been inserted in the queue (i.e. the next entry to be executed). */
+ uint8_t last; /**< Index of last entry to have been inserted in the queue. */
+ uint8_t size; /**< Queue size. */
+ timer_user_op_t user_op_queue[APP_TIMER_CONFIG_OP_QUEUE_SIZE+1]; /**< Queue buffer. */
+} timer_op_queue_t;
+
+STATIC_ASSERT(sizeof(timer_op_queue_t) % 4 == 0);
+
+#define CONTEXT_QUEUE_SIZE_MAX (2)
+
+static timer_op_queue_t m_op_queue; /**< Timer operations queue. */
+static timer_node_t * mp_timer_id_head; /**< First timer in list of running timers. */
+static uint32_t m_ticks_latest; /**< Last known RTC counter value. */
+static uint32_t m_ticks_elapsed[CONTEXT_QUEUE_SIZE_MAX]; /**< Timer internal elapsed ticks queue. */
+static uint8_t m_ticks_elapsed_q_read_ind; /**< Timer internal elapsed ticks queue read index. */
+static uint8_t m_ticks_elapsed_q_write_ind; /**< Timer internal elapsed ticks queue write index. */
+static bool m_rtc1_running; /**< Boolean indicating if RTC1 is running. */
+static bool m_rtc1_reset; /**< Boolean indicating if RTC1 counter has been reset due to last timer removed from timer list during the timer list handling. */
+
+#if APP_TIMER_WITH_PROFILER
+static uint8_t m_max_user_op_queue_utilization; /**< Maximum observed timer user operations queue utilization. */
+#endif
+
+/**@brief Function for initializing the RTC1 counter.
+ *
+ * @param[in] prescaler Value of the RTC1 PRESCALER register. Set to 0 for no prescaling.
+ */
+static void rtc1_init(uint32_t prescaler)
+{
+ NRF_RTC1->PRESCALER = prescaler;
+ NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI);
+}
+
+
+/**@brief Function for starting the RTC1 timer.
+ */
+static void rtc1_start(void)
+{
+ NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk;
+ NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
+
+ NVIC_ClearPendingIRQ(RTC1_IRQn);
+ NVIC_EnableIRQ(RTC1_IRQn);
+
+ NRF_RTC1->TASKS_START = 1;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+
+ m_rtc1_running = true;
+}
+
+
+/**@brief Function for stopping the RTC1 timer.
+ */
+static void rtc1_stop(void)
+{
+ NVIC_DisableIRQ(RTC1_IRQn);
+
+ NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
+ NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
+
+ NRF_RTC1->TASKS_STOP = 1;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+
+ NRF_RTC1->TASKS_CLEAR = 1;
+ m_ticks_latest = 0;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+
+ m_rtc1_running = false;
+}
+
+
+/**@brief Function for returning the current value of the RTC1 counter.
+ *
+ * @return Current value of the RTC1 counter.
+ */
+static __INLINE uint32_t rtc1_counter_get(void)
+{
+ return NRF_RTC1->COUNTER;
+}
+
+
+/**@brief Function for computing the difference between two RTC1 counter values.
+ *
+ * @return Number of ticks elapsed from ticks_old to ticks_now.
+ */
+static __INLINE uint32_t ticks_diff_get(uint32_t ticks_now, uint32_t ticks_old)
+{
+ return ((ticks_now - ticks_old) & MAX_RTC_COUNTER_VAL);
+}
+
+
+/**@brief Function for setting the RTC1 Capture Compare register 0, and enabling the corresponding
+ * event.
+ *
+ * @param[in] value New value of Capture Compare register 0.
+ */
+static __INLINE void rtc1_compare0_set(uint32_t value)
+{
+ NRF_RTC1->CC[0] = value;
+}
+
+
+/**@brief Function for inserting a timer in the timer list.
+ *
+ * @param[in] timer_id Id of timer to insert.
+ */
+static void timer_list_insert(timer_node_t * p_timer)
+{
+ if (mp_timer_id_head == NULL)
+ {
+ mp_timer_id_head = p_timer;
+ }
+ else
+ {
+ if (p_timer->ticks_to_expire <= mp_timer_id_head->ticks_to_expire)
+ {
+ mp_timer_id_head->ticks_to_expire -= p_timer->ticks_to_expire;
+
+ p_timer->next = mp_timer_id_head;
+ mp_timer_id_head = p_timer;
+ }
+ else
+ {
+ timer_node_t * p_previous;
+ timer_node_t * p_current;
+ uint32_t ticks_to_expire;
+
+ ticks_to_expire = p_timer->ticks_to_expire;
+ p_previous = mp_timer_id_head;
+ p_current = mp_timer_id_head;
+
+ while ((p_current != NULL) && (ticks_to_expire > p_current->ticks_to_expire))
+ {
+ ticks_to_expire -= p_current->ticks_to_expire;
+ p_previous = p_current;
+ p_current = p_current->next;
+ }
+
+ if (p_current != NULL)
+ {
+ p_current->ticks_to_expire -= ticks_to_expire;
+ }
+
+ p_timer->ticks_to_expire = ticks_to_expire;
+ p_timer->next = p_current;
+ p_previous->next = p_timer;
+ }
+ }
+}
+
+
+/**@brief Function for removing a timer from the timer queue.
+ *
+ * @param[in] timer_id Id of timer to remove.
+ *
+ * @return TRUE if Capture Compare register must be updated, FALSE otherwise.
+ */
+static bool timer_list_remove(timer_node_t * p_timer)
+{
+ timer_node_t * p_old_head;
+ timer_node_t * p_previous;
+ timer_node_t * p_current;
+ uint32_t timeout;
+
+ // Find the timer's position in timer list.
+ p_old_head = mp_timer_id_head;
+ p_previous = mp_timer_id_head;
+ p_current = p_previous;
+
+ while (p_current != NULL)
+ {
+ if (p_current == p_timer)
+ {
+ break;
+ }
+ p_previous = p_current;
+ p_current = p_current->next;
+ }
+
+ // Timer not in active list.
+ if (p_current == NULL)
+ {
+ return false;
+ }
+
+ // Timer is the first in the list
+ if (p_previous == p_current)
+ {
+ mp_timer_id_head = mp_timer_id_head->next;
+
+ // No more timers in the list. Reset RTC1 in case Start timer operations are present in the queue.
+ if (mp_timer_id_head == NULL)
+ {
+ NRF_RTC1->TASKS_CLEAR = 1;
+ m_ticks_latest = 0;
+ m_rtc1_reset = true;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+ }
+ }
+
+ // Remaining timeout between next timeout.
+ timeout = p_current->ticks_to_expire;
+
+ // Link previous timer with next of this timer, i.e. removing the timer from list.
+ p_previous->next = p_current->next;
+
+ // If this is not the last timer, increment the next timer by this timer timeout.
+ p_current = p_previous->next;
+ if (p_current != NULL)
+ {
+ p_current->ticks_to_expire += timeout;
+ }
+
+ return (p_old_head != mp_timer_id_head);
+}
+
+
+/**@brief Function for scheduling a check for timeouts by generating a RTC1 interrupt.
+ */
+static void timer_timeouts_check_sched(void)
+{
+ NVIC_SetPendingIRQ(RTC1_IRQn);
+}
+
+
+/**@brief Function for scheduling a timer list update by generating a SWI interrupt.
+ */
+static void timer_list_handler_sched(void)
+{
+ NVIC_SetPendingIRQ(SWI_IRQn);
+}
+
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+static void timeout_handler_scheduled_exec(void * p_event_data, uint16_t event_size)
+{
+ APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t));
+ app_timer_event_t const * p_timer_event = (app_timer_event_t *)p_event_data;
+
+ p_timer_event->timeout_handler(p_timer_event->p_context);
+}
+#endif
+
+/**@brief Function for executing an application timeout handler, either by calling it directly, or
+ * by passing an event to the @ref app_scheduler.
+ *
+ * @param[in] p_timer Pointer to expired timer.
+ */
+static void timeout_handler_exec(timer_node_t * p_timer)
+{
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+ app_timer_event_t timer_event;
+
+ timer_event.timeout_handler = p_timer->p_timeout_handler;
+ timer_event.p_context = p_timer->p_context;
+ uint32_t err_code = app_sched_event_put(&timer_event, sizeof(timer_event), timeout_handler_scheduled_exec);
+ APP_ERROR_CHECK(err_code);
+#else
+ p_timer->p_timeout_handler(p_timer->p_context);
+#endif
+}
+
+
+/**@brief Function for checking for expired timers.
+ */
+static void timer_timeouts_check(void)
+{
+ // Handle expired of timer
+ if (mp_timer_id_head != NULL)
+ {
+ timer_node_t * p_timer;
+ timer_node_t * p_previous_timer;
+ uint32_t ticks_elapsed;
+ uint32_t ticks_expired;
+
+ // Initialize actual elapsed ticks being consumed to 0.
+ ticks_expired = 0;
+
+ // ticks_elapsed is collected here, job will use it.
+ ticks_elapsed = ticks_diff_get(rtc1_counter_get(), m_ticks_latest);
+
+ // Auto variable containing the head of timers expiring.
+ p_timer = mp_timer_id_head;
+
+ // Expire all timers within ticks_elapsed and collect ticks_expired.
+ while (p_timer != NULL)
+ {
+ // Do nothing if timer did not expire.
+ if (ticks_elapsed < p_timer->ticks_to_expire)
+ {
+ break;
+ }
+
+ // Decrement ticks_elapsed and collect expired ticks.
+ ticks_elapsed -= p_timer->ticks_to_expire;
+ ticks_expired += p_timer->ticks_to_expire;
+
+ // Move to next timer.
+ p_previous_timer = p_timer;
+ p_timer = p_timer->next;
+
+ // Execute Task.
+ if (p_previous_timer->is_running)
+ {
+ p_previous_timer->is_running = false;
+ timeout_handler_exec(p_previous_timer);
+ }
+ }
+
+ // Prepare to queue the ticks expired in the m_ticks_elapsed queue.
+ if (m_ticks_elapsed_q_read_ind == m_ticks_elapsed_q_write_ind)
+ {
+ // The read index of the queue is equal to the write index. This means the new
+ // value of ticks_expired should be stored at a new location in the m_ticks_elapsed
+ // queue (which is implemented as a double buffer).
+
+ // Check if there will be a queue overflow.
+ if (++m_ticks_elapsed_q_write_ind == CONTEXT_QUEUE_SIZE_MAX)
+ {
+ // There will be a queue overflow. Hence the write index should point to the start
+ // of the queue.
+ m_ticks_elapsed_q_write_ind = 0;
+ }
+ }
+
+ // Queue the ticks expired.
+ m_ticks_elapsed[m_ticks_elapsed_q_write_ind] = ticks_expired;
+
+ timer_list_handler_sched();
+ }
+}
+
+
+/**@brief Function for acquiring the number of ticks elapsed.
+ *
+ * @param[out] p_ticks_elapsed Number of ticks elapsed.
+ *
+ * @return TRUE if elapsed ticks was read from queue, FALSE otherwise.
+ */
+static bool elapsed_ticks_acquire(uint32_t * p_ticks_elapsed)
+{
+ // Pick the elapsed value from queue.
+ if (m_ticks_elapsed_q_read_ind != m_ticks_elapsed_q_write_ind)
+ {
+ // Dequeue elapsed value.
+ m_ticks_elapsed_q_read_ind++;
+ if (m_ticks_elapsed_q_read_ind == CONTEXT_QUEUE_SIZE_MAX)
+ {
+ m_ticks_elapsed_q_read_ind = 0;
+ }
+
+ *p_ticks_elapsed = m_ticks_elapsed[m_ticks_elapsed_q_read_ind];
+
+ m_ticks_latest += *p_ticks_elapsed;
+ m_ticks_latest &= MAX_RTC_COUNTER_VAL;
+
+ return true;
+ }
+ else
+ {
+ // No elapsed value in queue.
+ *p_ticks_elapsed = 0;
+ return false;
+ }
+}
+
+
+/**@brief Function for updating the timer list for expired timers.
+ *
+ * @param[in] ticks_elapsed Number of elapsed ticks.
+ * @param[in] ticks_previous Previous known value of the RTC counter.
+ * @param[out] p_restart_list_head List of repeating timers to be restarted.
+ */
+static void expired_timers_handler(uint32_t ticks_elapsed,
+ uint32_t ticks_previous,
+ timer_node_t ** p_restart_list_head)
+{
+ uint32_t ticks_expired = 0;
+
+ while (mp_timer_id_head != NULL)
+ {
+ timer_node_t * p_timer;
+ timer_node_t * p_timer_expired;
+
+ // Auto variable for current timer node.
+ p_timer = mp_timer_id_head;
+
+ // Do nothing if timer did not expire
+ if (ticks_elapsed < p_timer->ticks_to_expire)
+ {
+ p_timer->ticks_to_expire -= ticks_elapsed;
+ break;
+ }
+
+ // Decrement ticks_elapsed and collect expired ticks.
+ ticks_elapsed -= p_timer->ticks_to_expire;
+ ticks_expired += p_timer->ticks_to_expire;
+
+ // Timer expired, set ticks_to_expire zero.
+ p_timer->ticks_to_expire = 0;
+
+ // Remove the expired timer from head.
+ p_timer_expired = mp_timer_id_head;
+ mp_timer_id_head = p_timer->next;
+
+ // Timer will be restarted if periodic.
+ if (p_timer->ticks_periodic_interval != 0)
+ {
+ p_timer->ticks_at_start = (ticks_previous + ticks_expired) & MAX_RTC_COUNTER_VAL;
+ p_timer->ticks_first_interval = p_timer->ticks_periodic_interval;
+ p_timer->next = *p_restart_list_head;
+ *p_restart_list_head = p_timer_expired;
+ }
+ }
+}
+
+
+/**@brief Function for handling timer list insertions.
+ *
+ * @param[in] p_restart_list_head List of repeating timers to be restarted.
+ *
+ * @return TRUE if Capture Compare register must be updated, FALSE otherwise.
+ */
+static bool list_insertions_handler(timer_node_t * p_restart_list_head)
+{
+ bool compare_update = false;
+
+ timer_node_t * p_timer_id_old_head;
+
+ // Remember the old head, so as to decide if new compare needs to be set.
+ p_timer_id_old_head = mp_timer_id_head;
+
+ // Handle insertions of timers.
+ while ((p_restart_list_head != NULL) || (m_op_queue.first != m_op_queue.last))
+ {
+ timer_node_t * p_timer;
+
+ if (p_restart_list_head != NULL)
+ {
+ p_timer = p_restart_list_head;
+ p_restart_list_head = p_timer->next;
+ }
+ else
+ {
+ timer_user_op_t * p_user_op = &m_op_queue.user_op_queue[m_op_queue.first];
+
+ m_op_queue.first++;
+ if (m_op_queue.first == m_op_queue.size)
+ {
+ m_op_queue.first = 0;
+ }
+
+ p_timer = p_user_op->p_node;
+
+ switch (p_user_op->op_type)
+ {
+ case TIMER_USER_OP_TYPE_STOP:
+ // Delete node if timer is running.
+ if (timer_list_remove(p_user_op->p_node))
+ {
+ compare_update = true;
+ }
+
+ p_timer->is_running = false;
+ continue;
+
+ case TIMER_USER_OP_TYPE_STOP_ALL:
+ // Delete list of running timers, and mark all timers as not running.
+ while (mp_timer_id_head != NULL)
+ {
+ timer_node_t * p_head = mp_timer_id_head;
+
+ p_head->is_running = false;
+ mp_timer_id_head = p_head->next;
+ }
+ continue;
+ case TIMER_USER_OP_TYPE_START:
+ break;
+ default:
+ // No implementation needed.
+ continue;
+ }
+
+ if (p_timer->is_running)
+ {
+ continue;
+ }
+
+ p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start;
+ p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval;
+ p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval;
+ p_timer->p_context = p_user_op->params.start.p_context;
+
+ if (m_rtc1_reset)
+ {
+ p_timer->ticks_at_start = 0;
+ }
+ }
+
+ // Prepare the node to be inserted.
+ if (
+ ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL)
+ <
+ (MAX_RTC_COUNTER_VAL / 2)
+ )
+ {
+ p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) +
+ p_timer->ticks_first_interval;
+ }
+ else
+ {
+ uint32_t delta_current_start;
+
+ delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start);
+ if (p_timer->ticks_first_interval > delta_current_start)
+ {
+ p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start;
+ }
+ else
+ {
+ p_timer->ticks_to_expire = 0;
+ }
+ }
+
+ p_timer->ticks_at_start = 0;
+ p_timer->ticks_first_interval = 0;
+ p_timer->is_running = true;
+ p_timer->next = NULL;
+
+ // Insert into list
+ timer_list_insert(p_timer);
+ }
+
+ return (compare_update || (mp_timer_id_head != p_timer_id_old_head));
+}
+
+
+/**@brief Function for updating the Capture Compare register.
+ */
+static void compare_reg_update(timer_node_t * p_timer_id_head_old)
+{
+ // Setup the timeout for timers on the head of the list
+ if (mp_timer_id_head != NULL)
+ {
+ uint32_t ticks_to_expire = mp_timer_id_head->ticks_to_expire;
+ uint32_t pre_counter_val = rtc1_counter_get();
+ uint32_t cc = m_ticks_latest;
+ uint32_t ticks_elapsed = ticks_diff_get(pre_counter_val, cc) + RTC_COMPARE_OFFSET_MIN;
+
+ if (!m_rtc1_running)
+ {
+ // No timers were already running, start RTC
+ rtc1_start();
+ }
+
+ cc += (ticks_elapsed < ticks_to_expire) ? ticks_to_expire : ticks_elapsed;
+ cc &= MAX_RTC_COUNTER_VAL;
+
+ rtc1_compare0_set(cc);
+
+ uint32_t post_counter_val = rtc1_counter_get();
+
+ if (
+ (ticks_diff_get(post_counter_val, pre_counter_val) + RTC_COMPARE_OFFSET_MIN)
+ >
+ ticks_diff_get(cc, pre_counter_val)
+ )
+ {
+ // When this happens the COMPARE event may not be triggered by the RTC.
+ // The nRF51 Series User Specification states that if the COUNTER value is N
+ // (i.e post_counter_val = N), writing N or N + 1 to a CC register may not trigger a
+ // COMPARE event. Hence the RTC interrupt is forcefully pended by calling the following
+ // function.
+ rtc1_compare0_set(rtc1_counter_get()); // this should prevent CC to fire again in the background while the code is in RTC-ISR
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+ timer_timeouts_check_sched();
+ }
+ }
+ else
+ {
+#if (APP_TIMER_KEEPS_RTC_ACTIVE == 0)
+ // No timers are running, stop RTC
+ rtc1_stop();
+#endif //(APP_TIMER_KEEPS_RTC_ACTIVE == 0)
+ }
+}
+
+
+/**@brief Function for handling changes to the timer list.
+ */
+static void timer_list_handler(void)
+{
+ timer_node_t * p_restart_list_head = NULL;
+
+ uint32_t ticks_elapsed;
+ uint32_t ticks_previous;
+ bool ticks_have_elapsed;
+ bool compare_update = false;
+ timer_node_t * p_timer_id_head_old;
+
+#if APP_TIMER_WITH_PROFILER
+ {
+ uint8_t size = m_op_queue.size;
+ uint8_t first = m_op_queue.first;
+ uint8_t last = m_op_queue.last;
+ uint8_t utilization = (first <= last) ? (last - first) : (size + 1 - first + last);
+
+ if (utilization > m_max_user_op_queue_utilization)
+ {
+ m_max_user_op_queue_utilization = utilization;
+ }
+ }
+#endif
+
+ // Back up the previous known tick and previous list head
+ ticks_previous = m_ticks_latest;
+ p_timer_id_head_old = mp_timer_id_head;
+
+ // Get number of elapsed ticks
+ ticks_have_elapsed = elapsed_ticks_acquire(&ticks_elapsed);
+
+ // Handle expired timers
+ if (ticks_have_elapsed)
+ {
+ expired_timers_handler(ticks_elapsed, ticks_previous, &p_restart_list_head);
+ compare_update = true;
+ }
+
+
+ // Handle list insertions
+ if (list_insertions_handler(p_restart_list_head))
+ {
+ compare_update = true;
+ }
+
+ // Update compare register if necessary
+ if (compare_update)
+ {
+ compare_reg_update(p_timer_id_head_old);
+ }
+ m_rtc1_reset = false;
+}
+
+
+/**@brief Function for enqueueing a new operations queue entry.
+ *
+ * @param[in] last_index Index of the next last index to be enqueued.
+ */
+static void user_op_enque(uint8_t last_index)
+{
+ m_op_queue.last = last_index;
+}
+
+
+/**@brief Function for allocating a new operations queue entry.
+ *
+ * @param[out] p_last_index Index of the next last index to be enqueued.
+ *
+ * @return Pointer to allocated queue entry, or NULL if queue is full.
+ */
+static timer_user_op_t * user_op_alloc( uint8_t * p_last_index)
+{
+ uint8_t last;
+ timer_user_op_t * p_user_op;
+
+ last = m_op_queue.last + 1;
+ if (last == m_op_queue.size)
+ {
+ // Overflow case.
+ last = 0;
+ }
+ if (last == m_op_queue.first)
+ {
+ // Queue is full.
+ return NULL;
+ }
+
+ *p_last_index = last;
+ p_user_op = &m_op_queue.user_op_queue[m_op_queue.last];
+
+ return p_user_op;
+}
+
+
+/**@brief Function for scheduling a Timer Start operation.
+ *
+ * @param[in] timer_id Id of timer to start.
+ * @param[in] timeout_initial Time (in ticks) to first timer expiry.
+ * @param[in] timeout_periodic Time (in ticks) between periodic expiries.
+ * @param[in] p_context General purpose pointer. Will be passed to the timeout handler when
+ * the timer expires.
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+
+static uint32_t timer_start_op_schedule(timer_node_t * p_node,
+ uint32_t timeout_initial,
+ uint32_t timeout_periodic,
+ void * p_context)
+{
+ uint8_t last_index;
+ uint32_t err_code = NRF_SUCCESS;
+
+ CRITICAL_REGION_ENTER();
+ timer_user_op_t * p_user_op = user_op_alloc(&last_index);
+ if (p_user_op == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ p_user_op->op_type = TIMER_USER_OP_TYPE_START;
+ p_user_op->p_node = p_node;
+ p_user_op->params.start.ticks_at_start = rtc1_counter_get();
+ p_user_op->params.start.ticks_first_interval = timeout_initial;
+ p_user_op->params.start.ticks_periodic_interval = timeout_periodic;
+ p_user_op->params.start.p_context = p_context;
+
+ user_op_enque(last_index);
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ timer_list_handler_sched();
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for scheduling a Timer Stop operation.
+ *
+ * @param[in] timer_id Id of timer to stop.
+ * @param[in] op_type Type of stop operation
+ *
+ * @return NRF_SUCCESS on successful scheduling a timer stop operation. NRF_ERROR_NO_MEM when there
+ * is no memory left to schedule the timer stop operation.
+ */
+static uint32_t timer_stop_op_schedule(timer_node_t * p_node,
+ timer_user_op_type_t op_type)
+{
+ uint8_t last_index;
+ uint32_t err_code = NRF_SUCCESS;
+
+ CRITICAL_REGION_ENTER();
+ timer_user_op_t * p_user_op = user_op_alloc(&last_index);
+ if (p_user_op == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ p_user_op->op_type = op_type;
+ p_user_op->p_node = p_node;
+
+ user_op_enque(last_index);
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ timer_list_handler_sched();
+ }
+
+ return err_code;
+}
+
+/**@brief Function for handling the RTC1 interrupt.
+ *
+ * @details Checks for timeouts, and executes timeout handlers for expired timers.
+ */
+void RTC1_IRQHandler(void)
+{
+ // Clear all events (also unexpected ones)
+ NRF_RTC1->EVENTS_COMPARE[0] = 0;
+ NRF_RTC1->EVENTS_COMPARE[1] = 0;
+ NRF_RTC1->EVENTS_COMPARE[2] = 0;
+ NRF_RTC1->EVENTS_COMPARE[3] = 0;
+ NRF_RTC1->EVENTS_TICK = 0;
+ NRF_RTC1->EVENTS_OVRFLW = 0;
+
+ // Check for expired timers
+ timer_timeouts_check();
+}
+
+
+/**@brief Function for handling the SWI interrupt.
+ *
+ * @details Performs all updates to the timer list.
+ */
+void SWI_IRQHandler(void)
+{
+ timer_list_handler();
+}
+
+
+ret_code_t app_timer_init(void)
+{
+ // Stop RTC to prevent any running timers from expiring (in case of reinitialization)
+ rtc1_stop();
+
+ // Initialize operation queue
+ m_op_queue.first = 0;
+ m_op_queue.last = 0;
+ m_op_queue.size = APP_TIMER_CONFIG_OP_QUEUE_SIZE+1;
+
+ mp_timer_id_head = NULL;
+ m_ticks_elapsed_q_read_ind = 0;
+ m_ticks_elapsed_q_write_ind = 0;
+
+#if APP_TIMER_WITH_PROFILER
+ m_max_user_op_queue_utilization = 0;
+#endif
+
+ NVIC_ClearPendingIRQ(SWI_IRQn);
+ NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
+ NVIC_EnableIRQ(SWI_IRQn);
+
+ rtc1_init(APP_TIMER_CONFIG_RTC_FREQUENCY);
+
+ m_ticks_latest = rtc1_counter_get();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+ // Check state and parameters
+ VERIFY_MODULE_INITIALIZED();
+
+ if (timeout_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_timer_id == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (((timer_node_t*)*p_timer_id)->is_running)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ timer_node_t * p_node = (timer_node_t *)*p_timer_id;
+ p_node->is_running = false;
+ p_node->mode = mode;
+ p_node->p_timeout_handler = timeout_handler;
+ return NRF_SUCCESS;
+}
+
+ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
+{
+ uint32_t timeout_periodic;
+ timer_node_t * p_node = (timer_node_t*)timer_id;
+
+ // Check state and parameters
+ VERIFY_MODULE_INITIALIZED();
+
+ if (timer_id == 0)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_node->p_timeout_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Schedule timer start operation
+ timeout_periodic = (p_node->mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0;
+
+ return timer_start_op_schedule(p_node,
+ timeout_ticks,
+ timeout_periodic,
+ p_context);
+}
+
+
+ret_code_t app_timer_stop(app_timer_id_t timer_id)
+{
+ timer_node_t * p_node = (timer_node_t*)timer_id;
+ // Check state and parameters
+ VERIFY_MODULE_INITIALIZED();
+
+ if ((timer_id == NULL) || (p_node->p_timeout_handler == NULL))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_node->is_running = false;
+
+ // Schedule timer stop operation
+ return timer_stop_op_schedule(p_node, TIMER_USER_OP_TYPE_STOP);
+}
+
+
+ret_code_t app_timer_stop_all(void)
+{
+ // Check state
+ VERIFY_MODULE_INITIALIZED();
+
+ return timer_stop_op_schedule(NULL, TIMER_USER_OP_TYPE_STOP_ALL);
+}
+
+
+uint32_t app_timer_cnt_get(void)
+{
+ return rtc1_counter_get();
+}
+
+
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from)
+{
+ return ticks_diff_get(ticks_to, ticks_from);
+}
+
+#if APP_TIMER_WITH_PROFILER
+uint8_t app_timer_op_queue_utilization_get(void)
+{
+ return m_max_user_op_queue_utilization;
+}
+#endif
+
+void app_timer_pause(void)
+{
+ NRF_RTC1->TASKS_STOP = 1;
+}
+
+void app_timer_resume(void)
+{
+ NRF_RTC1->TASKS_START = 1;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h
new file mode 100644
index 0000000..64540a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h
@@ -0,0 +1,313 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup 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 invocation 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 "sdk_config.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "compiler_abstraction.h"
+#include "nordic_common.h"
+#ifdef APP_TIMER_V2
+#include "nrf_log_instance.h"
+#include "nrf_sortlist.h"
+#endif
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define APP_TIMER_LOG_NAME app_timer
+
+#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(). */
+
+#ifdef RTX
+#define APP_TIMER_NODE_SIZE 40 /**< Size of app_timer.timer_node_t (used to allocate data). */
+#else
+#define APP_TIMER_NODE_SIZE 32 /**< Size of app_timer.timer_node_t (used to allocate data). */
+#endif // RTX
+
+#define APP_TIMER_SCHED_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Size of event data when scheduler is used. */
+
+#define APP_TIMER_MAX_CNT_VAL RTC_COUNTER_COUNTER_Msk /**< Maximum counter value that can be returned by @ref app_timer_cnt_get. */
+
+/**@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.
+ *
+ * @param[in] MS Milliseconds.
+ *
+ * @return Number of timer ticks.
+ */
+#ifndef FREERTOS
+#define APP_TIMER_TICKS(MS) \
+ ((uint32_t)ROUNDED_DIV( \
+ (MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, \
+ 1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1)))
+#else
+#include "FreeRTOSConfig.h"
+#define APP_TIMER_TICKS(MS) (uint32_t)ROUNDED_DIV((MS)*configTICK_RATE_HZ,1000)
+#endif
+
+
+/**
+ * @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) _APP_TIMER_DEF(timer_id)
+
+/**@brief Application time-out handler type. */
+typedef void (*app_timer_timeout_handler_t)(void * p_context);
+
+#ifdef APP_TIMER_V2
+/**
+ * @brief app_timer control block
+ */
+typedef struct
+{
+ nrf_sortlist_item_t list_item; /**< Token used by sortlist. */
+ volatile uint32_t end_val; /**< RTC counter value when timer expires. */
+ uint32_t repeat_period; /**< Repeat period (0 if single shot mode). */
+ app_timer_timeout_handler_t handler; /**< User handler. */
+ void * p_context; /**< User context. */
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) /**< Pointer to instance of the logger object (Conditionally compiled). */
+ volatile bool active; /**< Flag indicating that timer is active. */
+} 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;
+
+#define _APP_TIMER_DEF(timer_id) \
+ NRF_LOG_INSTANCE_REGISTER(APP_TIMER_LOG_NAME, timer_id, \
+ APP_TIMER_CONFIG_INFO_COLOR, \
+ APP_TIMER_CONFIG_DEBUG_COLOR, \
+ APP_TIMER_CONFIG_INITIAL_LOG_LEVEL, \
+ APP_TIMER_CONFIG_LOG_ENABLED ? \
+ APP_TIMER_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ static app_timer_t CONCAT_2(timer_id,_data) = { \
+ .active = false, \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, APP_TIMER_LOG_NAME, timer_id) \
+ }; \
+ static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
+
+#else //APP_TIMER_V2
+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;
+
+#define _APP_TIMER_DEF(timer_id) \
+ static app_timer_t CONCAT_2(timer_id,_data) = { {0} }; \
+ static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
+
+#endif
+
+
+/**@brief Structure passed to app_scheduler. */
+typedef struct
+{
+ app_timer_timeout_handler_t timeout_handler;
+ void * p_context;
+} app_timer_event_t;
+
+/**@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 Function for initializing the timer module.
+ *
+ * @retval NRF_SUCCESS If the module was initialized successfully.
+ */
+ret_code_t app_timer_init(void);
+
+/**@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.
+ */
+ret_code_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.
+ */
+ret_code_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.
+ */
+ret_code_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.
+ */
+ret_code_t app_timer_stop_all(void);
+
+/**@brief Function for returning the current value of the RTC1 counter.
+ *
+ * @return Current value of the RTC1 counter.
+ */
+uint32_t app_timer_cnt_get(void);
+
+/**@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().
+ *
+ * @return Number of ticks from ticks_from to ticks_to.
+ */
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from);
+
+
+/**@brief Function for getting the maximum observed operation queue utilization.
+ *
+ * Function for tuning the module and determining OP_QUEUE_SIZE value and thus module RAM usage.
+ *
+ * @note APP_TIMER_WITH_PROFILER must be enabled to use this functionality.
+ *
+ * @return Maximum number of events in queue observed so far.
+ */
+uint8_t app_timer_op_queue_utilization_get(void);
+
+/**
+ * @brief Function for pausing RTC activity which drives app_timer.
+ *
+ * @note This function can be used for debugging purposes to ensure
+ * that application is halted when entering a breakpoint.
+ */
+void app_timer_pause(void);
+
+/**
+ * @brief Function for resuming RTC activity which drives app_timer.
+ *
+ * @note This function can be used for debugging purposes to resume
+ * application activity.
+ */
+void app_timer_resume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_TIMER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c
new file mode 100644
index 0000000..bea64fd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_TIMER)
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+
+#include "app_timer.h"
+#include <stdlib.h>
+#include <string.h>
+#include "nrf.h"
+#include "app_error.h"
+
+/**
+ * Note that this implementation is made only for enable SDK components which interacts with app_timer to work with FreeRTOS.
+ * It is more suitable to use native FreeRTOS timer for other purposes.
+ */
+/* Check if RTC FreeRTOS version is used */
+#if configTICK_SOURCE != FREERTOS_USE_RTC
+#error app_timer in FreeRTOS variant have to be used with RTC tick source configuration. Default configuration have to be used in other case.
+#endif
+
+/**
+ * @brief Waiting time for the timer queue
+ *
+ * Number of system ticks to wait for the timer queue to put the message.
+ * It is strongly recommended to set this to the value bigger than 1.
+ * In other case if timer message queue is full - any operation on timer may fail.
+ * @note
+ * Timer functions called from interrupt context would never wait.
+ */
+#define APP_TIMER_WAIT_FOR_QUEUE 2
+
+/**@brief This structure keeps information about osTimer.*/
+typedef struct
+{
+ void * argument;
+ TimerHandle_t osHandle;
+ app_timer_timeout_handler_t func;
+ /**
+ * This member is to make sure that timer function is only called if timer is running.
+ * FreeRTOS may have timer running even after stop function is called,
+ * because it processes commands in Timer task and stopping function only puts command into the queue. */
+ bool active;
+}app_timer_info_t;
+
+
+/* Check if freeRTOS timers are activated */
+#if configUSE_TIMERS == 0
+ #error app_timer for freeRTOS requires configUSE_TIMERS option to be activated.
+#endif
+
+/* Check if app_timer_t variable type can held our app_timer_info_t structure */
+STATIC_ASSERT(sizeof(app_timer_info_t) <= sizeof(app_timer_t));
+
+
+/**
+ * @brief Internal callback function for the system timer
+ *
+ * Internal function that is called from the system timer.
+ * It gets our parameter from timer data and sends it to user function.
+ * @param[in] xTimer Timer handler
+ */
+static void app_timer_callback(TimerHandle_t xTimer)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(pvTimerGetTimerID(xTimer));
+ ASSERT(pinfo->osHandle == xTimer);
+ ASSERT(pinfo->func != NULL);
+
+ if (pinfo->active)
+ pinfo->func(pinfo->argument);
+}
+
+
+uint32_t app_timer_init(void)
+{
+ return NRF_SUCCESS;
+}
+
+
+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)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(*p_timer_id);
+ uint32_t err_code = NRF_SUCCESS;
+ unsigned long timer_mode;
+
+ if ((timeout_handler == NULL) || (p_timer_id == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (pinfo->active)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (pinfo->osHandle == NULL)
+ {
+ /* New timer is created */
+ memset(pinfo, 0, sizeof(app_timer_info_t));
+
+ if (mode == APP_TIMER_MODE_SINGLE_SHOT)
+ timer_mode = pdFALSE;
+ else
+ timer_mode = pdTRUE;
+
+ pinfo->func = timeout_handler;
+ pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback);
+
+ if (pinfo->osHandle == NULL)
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ /* Timer cannot be reinitialized using FreeRTOS API */
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id);
+ TimerHandle_t hTimer = pinfo->osHandle;
+
+ if (hTimer == NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (pinfo->active && (xTimerIsTimerActive(hTimer) != pdFALSE))
+ {
+ // Timer already running - exit silently
+ return NRF_SUCCESS;
+ }
+
+ pinfo->argument = p_context;
+
+ if (__get_IPSR() != 0)
+ {
+ BaseType_t yieldReq = pdFALSE;
+ if (xTimerChangePeriodFromISR(hTimer, timeout_ticks, &yieldReq) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ if ( xTimerStartFromISR(hTimer, &yieldReq) != pdPASS )
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ portYIELD_FROM_ISR(yieldReq);
+ }
+ else
+ {
+ if (xTimerChangePeriod(hTimer, timeout_ticks, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ if (xTimerStart(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+
+ pinfo->active = true;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_timer_stop(app_timer_id_t timer_id)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id);
+ TimerHandle_t hTimer = pinfo->osHandle;
+ if (hTimer == NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (__get_IPSR() != 0)
+ {
+ BaseType_t yieldReq = pdFALSE;
+ if (xTimerStopFromISR(hTimer, &yieldReq) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ portYIELD_FROM_ISR(yieldReq);
+ }
+ else
+ {
+ if (xTimerStop(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+
+ pinfo->active = false;
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c
new file mode 100644
index 0000000..b12982f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c
@@ -0,0 +1,278 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_TIMER)
+#include "app_timer.h"
+#include <stdlib.h>
+#include "nrf.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+#include "cmsis_os.h"
+#include "app_util_platform.h"
+
+#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt. */
+
+#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */
+
+/**@brief This structure keeps information about osTimer.*/
+typedef struct
+{
+ osTimerDef_t timerDef;
+ uint32_t buffer[6];
+ osTimerId id;
+}app_timer_info_t;
+
+/**@brief Store an array of timers with configuration. */
+typedef struct
+{
+ uint8_t max_timers; /**< The maximum number of timers*/
+ uint32_t prescaler;
+ app_timer_info_t * app_timers; /**< Pointer to table of timers*/
+}app_timer_control_t;
+
+app_timer_control_t app_timer_control;
+
+/**@brief This structure is defined by RTX. It keeps information about created osTimers. It is used in app_timer_start(). */
+typedef struct os_timer_cb_
+{
+ struct os_timer_cb_ * next; /**< Pointer to next active Timer */
+ uint8_t state; /**< Timer State */
+ uint8_t type; /**< Timer Type (Periodic/One-shot). */
+ uint16_t reserved; /**< Reserved. */
+ uint32_t tcnt; /**< Timer Delay Count. */
+ uint32_t icnt; /**< Timer Initial Count. */
+ void * arg; /**< Timer Function Argument. */
+ const osTimerDef_t * timer; /**< Pointer to Timer definition. */
+} os_timer_cb;
+
+/**@brief This functions are defined by RTX.*/
+//lint --save -e10 -e19 -e526
+extern osStatus svcTimerStop(osTimerId timer_id); /**< Used in app_timer_stop(). */
+extern osStatus svcTimerStart(osTimerId timer_id, uint32_t millisec); /**< Used in app_timer_start(). */
+// lint --restore
+static void * rt_id2obj (void *id) /**< Used in app_timer_start(). This function gives information if osTimerID is valid */
+{
+ if ((uint32_t)id & 3U)
+ {
+ return NULL;
+ }
+
+#ifdef OS_SECTIONS_LINK_INFO
+
+ if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U))
+ {
+ if (id < (void *)os_section_id$$Base)
+ {
+ return NULL;
+ }
+
+ if (id >= (void *)os_section_id$$Limit)
+ {
+ return NULL;
+ }
+ }
+#endif
+
+ return id;
+}
+
+
+
+ret_code_t app_timer_init(void)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_timer_control.app_timers = p_buffer;
+ NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+
+ if ((timeout_handler == NULL) || (p_timer_id == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_timer_info_t * p_timer_info = (app_timer_info_t *)*p_timer_id;
+ p_timer_info->timerDef.timer = p_timer_info->buffer;
+ p_timer_info->timerDef.ptimer = (os_ptimer)timeout_handler;
+
+ p_timer_info->id = osTimerCreate(&(p_timer_info->timerDef), (os_timer_type)mode, NULL);
+
+ if (p_timer_info->id)
+ return NRF_SUCCESS;
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM; // This error is unspecified by rtx
+ }
+}
+
+#define osTimerRunning 2
+ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
+{
+ if ((timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint32_t timeout_ms =
+ ((uint32_t)ROUNDED_DIV(timeout_ticks * 1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1),
+ (uint32_t)APP_TIMER_CLOCK_FREQ));
+
+ app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id;
+ if (rt_id2obj((void *)p_timer_info->id) == NULL)
+ return NRF_ERROR_INVALID_PARAM;
+
+ // Pass p_context to timer_timeout_handler
+ ((os_timer_cb *)(p_timer_info->id))->arg = p_context;
+
+ if (((os_timer_cb *)(p_timer_info->id))->state == osTimerRunning)
+ {
+ return NRF_SUCCESS;
+ }
+ // osTimerStart() returns osErrorISR if it is called in interrupt routine.
+ switch (osTimerStart((osTimerId)p_timer_info->id, timeout_ms) )
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ break;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Start timer without svcCall
+ switch (svcTimerStart((osTimerId)p_timer_info->id, timeout_ms))
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ return NRF_ERROR_INVALID_STATE;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+
+ret_code_t app_timer_stop(app_timer_id_t timer_id)
+{
+ app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id;
+ switch (osTimerStop((osTimerId)p_timer_info->id) )
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ break;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ case osErrorResource:
+ return NRF_SUCCESS;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Stop timer without svcCall
+ switch (svcTimerStop((osTimerId)p_timer_info->id))
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ return NRF_ERROR_INVALID_STATE;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ case osErrorResource:
+ return NRF_SUCCESS;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+
+
+ret_code_t app_timer_stop_all(void)
+{
+ for (int i = 0; i < app_timer_control.max_timers; i++)
+ {
+ if (app_timer_control.app_timers[i].id)
+ {
+ (void)app_timer_stop((app_timer_id_t)app_timer_control.app_timers[i].id);
+ }
+ }
+ return 0;
+}
+
+
+extern uint32_t os_tick_val(void);
+uint32_t app_timer_cnt_get(void)
+{
+ return os_tick_val();
+}
+
+
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from)
+{
+ return ((ticks_to - ticks_from) & MAX_RTC_COUNTER_VAL);
+}
+#endif //NRF_MODULE_ENABLED(APP_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c
new file mode 100644
index 0000000..aefdb51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c
@@ -0,0 +1,568 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "app_timer.h"
+#include "nrf_atfifo.h"
+#include "nrf_sortlist.h"
+#include "nrf_delay.h"
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+#include "app_scheduler.h"
+#endif
+#include <stddef.h>
+#define NRF_LOG_MODULE_NAME APP_TIMER_LOG_NAME
+#if APP_TIMER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_TIMER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_TIMER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_TIMER_CONFIG_DEBUG_COLOR
+#else //APP_TIMER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_TIMER_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#include "drv_rtc.h"
+
+/**
+ * Maximum possible relative value is limited by safe window to detect cases when requested
+ * compare event has already occured.
+ */
+#define APP_TIMER_SAFE_WINDOW 1000
+
+#define APP_TIMER_RTC_MAX_VALUE (DRV_RTC_MAX_CNT - APP_TIMER_SAFE_WINDOW)
+
+static drv_rtc_t m_rtc_inst = DRV_RTC_INSTANCE(1);
+
+/**
+ * @brief Timer requests types.
+ */
+typedef enum
+{
+ TIMER_REQ_START,
+ TIMER_REQ_STOP,
+ TIMER_REQ_STOP_ALL
+} app_timer_req_type_t;
+
+/**
+ * @brief Operation request structure.
+ */
+typedef struct
+{
+ app_timer_req_type_t type; /**< Request type. */
+ app_timer_t * p_timer; /**< Timer instance. */
+} timer_req_t;
+
+static app_timer_t * volatile mp_active_timer; /**< Timer currently handled by RTC driver. */
+static bool m_global_active; /**< Flag used to globally disable all timers. */
+
+/* Request FIFO instance. */
+NRF_ATFIFO_DEF(m_req_fifo, timer_req_t, APP_TIMER_CONFIG_OP_QUEUE_SIZE);
+
+/* Sortlist instance. */
+static bool compare_func(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t *p_item1);
+NRF_SORTLIST_DEF(m_app_timer_sortlist, compare_func); /**< Sortlist used for storing queued timers. */
+
+/**
+ * @brief Function used for comparing items in sorted list.
+ */
+static inline bool compare_func(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t *p_item1)
+{
+ app_timer_t * p0 = CONTAINER_OF(p_item0, app_timer_t, list_item);
+ app_timer_t * p1 = CONTAINER_OF(p_item1, app_timer_t, list_item);
+
+ uint32_t p0_end = p0->end_val;
+ uint32_t p1_end = p1->end_val;
+ return (p0_end <= p1_end) ? true : false;
+}
+
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+static void scheduled_timeout_handler(void * p_event_data, uint16_t event_size)
+{
+ ASSERT(event_size == sizeof(app_timer_event_t));
+ app_timer_event_t const * p_timer_event = (app_timer_event_t *)p_event_data;
+
+ p_timer_event->timeout_handler(p_timer_event->p_context);
+}
+#endif
+
+/**
+ * @brief Function called on timer expiration
+ *
+ * Function calls user handler if timer was not stopped before. If timer is in repeated mode then
+ * timer is rescheduled.
+ *
+ * @param p_timer Timer instance.
+ *
+ * @return True if reevaluation of sortlist needed (becasue it was updated).
+ */
+static bool timer_expire(app_timer_t * p_timer)
+{
+ ASSERT(p_timer->handler);
+ bool ret = false;
+ if (m_global_active == true && p_timer != NULL && p_timer->active)
+ {
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+ app_timer_event_t timer_event;
+
+ timer_event.timeout_handler = p_timer->handler;
+ timer_event.p_context = p_timer->p_context;
+ uint32_t err_code = app_sched_event_put(&timer_event,
+ sizeof(timer_event),
+ scheduled_timeout_handler);
+ APP_ERROR_CHECK(err_code);
+#else
+ p_timer->handler(p_timer->p_context);
+#endif
+ if (p_timer->repeat_period && p_timer->active)
+ {
+ p_timer->end_val += p_timer->repeat_period;
+ nrf_sortlist_add(&m_app_timer_sortlist, &p_timer->list_item);
+ ret = true;
+ }
+ else
+ {
+ p_timer->active = false;
+ }
+ }
+ return ret;
+}
+
+/**
+ * @brief Function is configuring RTC driver to trigger timeout interrupt for given timer.
+ *
+ * It is possible that RTC driver will indicate that timeout already occured. In that case timer
+ * expires and function indicates that RTC was not configured.
+ *
+ * @param p_timer Timer instance.
+ * @param [in,out] p_rerun Flag indicating that sortlist reevaluation is required.
+ *
+ * @return True if RTC was successfully configured, false if timer already expired and RTC was not
+ * configured.
+ *
+ */
+static bool rtc_schedule(app_timer_t * p_timer, bool * p_rerun)
+{
+ ret_code_t ret = NRF_SUCCESS;
+ *p_rerun = false;
+ ret = drv_rtc_windowed_compare_set(&m_rtc_inst, 0, p_timer->end_val, APP_TIMER_SAFE_WINDOW);
+
+ if (ret == NRF_SUCCESS)
+ {
+ return true;
+ }
+ else if (ret == NRF_ERROR_TIMEOUT)
+ {
+ *p_rerun = timer_expire(p_timer);
+ }
+ else
+ {
+ ASSERT(0);
+ }
+ return false;
+}
+
+static inline app_timer_t * sortlist_pop(void)
+{
+ nrf_sortlist_item_t * p_next_item = nrf_sortlist_pop(&m_app_timer_sortlist);
+ return p_next_item ? CONTAINER_OF(p_next_item, app_timer_t, list_item) : NULL;
+}
+
+static inline app_timer_t * sortlist_peek(void)
+{
+ nrf_sortlist_item_t const * p_next_item = nrf_sortlist_peek(&m_app_timer_sortlist);
+ return p_next_item ? CONTAINER_OF(p_next_item, app_timer_t, list_item) : NULL;
+}
+
+static inline app_timer_t * sortlist_next(app_timer_t * p_item)
+{
+ nrf_sortlist_item_t const * p_next_item = nrf_sortlist_next(&p_item->list_item);
+ return p_next_item ? CONTAINER_OF(p_next_item, app_timer_t, list_item) : NULL;
+}
+/**
+ * @brief Function for deactivating all timers which are in the sorted list (active timers).
+ */
+static void sorted_list_stop_all(void)
+{
+ app_timer_t * p_next;
+ do
+ {
+ p_next = sortlist_pop();
+ if (p_next)
+ {
+ p_next->active = false;
+ }
+ } while (p_next);
+}
+
+/**
+ * @brief Function for handling RTC counter overflow.
+ *
+ * In case of overflow all active timers must have end value adjusted (reduced to 24 bit range).
+ */
+static void on_overflow_evt(void)
+{
+ NRF_LOG_DEBUG("Overflow EVT");
+ if (mp_active_timer)
+ {
+ uint32_t end_val = mp_active_timer->end_val;
+ mp_active_timer->end_val = end_val & RTC_COUNTER_COUNTER_Msk;
+ }
+
+ app_timer_t * p_next;
+ p_next = sortlist_peek();
+ while (p_next)
+ {
+ if (p_next->end_val <= RTC_COUNTER_COUNTER_Msk)
+ {
+ //If overflow occurs then all timers with value lower than max value expires immediately.
+ UNUSED_RETURN_VALUE(timer_expire(p_next));
+ }
+ else
+ {
+ p_next->end_val &= RTC_COUNTER_COUNTER_Msk;
+ }
+ p_next = sortlist_next(p_next);
+ }
+}
+
+/**
+ * #brief Function for handling RTC compare event - active timer expiration.
+ */
+static void on_compare_evt(void)
+{
+ if (mp_active_timer)
+ {
+ NRF_LOG_INST_DEBUG(mp_active_timer->p_log, "Compare EVT");
+ UNUSED_RETURN_VALUE(timer_expire(mp_active_timer));
+ mp_active_timer = NULL;
+ }
+ else
+ {
+ NRF_LOG_WARNING("Compare event but no active timer (already stopped?)");
+ }
+}
+
+/**
+ * @brief Function updates RTC.
+ *
+ * Function is called at the end of RTC interrupt when all new user request and/or timer expiration
+ * occured. It configures RTC if there is any pending timer, reconfigures if the are timers with
+ * shorted timeout than active one or stops RTC if there is no active timers.
+ */
+static void rtc_update(drv_rtc_t const * const p_instance)
+{
+ while(1)
+ {
+ app_timer_t * p_next = sortlist_peek();
+ bool rtc_reconf = false;
+ if (p_next) //Candidate for active timer
+ {
+ uint32_t next_end_val = p_next->end_val;
+ uint32_t active_end_val = mp_active_timer->end_val;
+ if (mp_active_timer == NULL)
+ {
+ //There is no active timer so candidate will become active timer.
+ rtc_reconf = true;
+ }
+ else if (mp_active_timer &&
+ (active_end_val > next_end_val))
+ {
+ //Candidate has shorter timeout than current active timer. Candidate will replace active timer.
+ //Active timer is put back into sorted list.
+ rtc_reconf = true;
+ if (mp_active_timer->active)
+ {
+ NRF_LOG_INST_DEBUG(mp_active_timer->p_log, "Timer preempted.");
+ nrf_sortlist_add(&m_app_timer_sortlist, &mp_active_timer->list_item);
+ }
+ }
+
+ if (rtc_reconf)
+ {
+ bool rerun;
+ p_next = sortlist_pop();
+ NRF_LOG_INST_DEBUG(p_next->p_log, "Activating timer (CC:%d).", next_end_val);
+ if (rtc_schedule(p_next, &rerun))
+ {
+ if (!APP_TIMER_KEEPS_RTC_ACTIVE && (mp_active_timer == NULL))
+ {
+ drv_rtc_start(p_instance);
+ }
+ mp_active_timer = p_next;
+
+ if (rerun == false)
+ {
+ //RTC was successfully updated and sortlist was not updated. Function can be terminated.
+ break;
+ }
+ }
+ else
+ {
+ //If RTC driver indicated that timeout already occured a new candidate will be taken from sorted list.
+ NRF_LOG_INST_DEBUG(p_next->p_log,"Timer expired before scheduled to RTC.");
+ }
+ }
+ else
+ {
+ //RTC will not be updated. Function can terminate.
+ break;
+ }
+ }
+ else //No candidate for active timer.
+ {
+ if (!APP_TIMER_KEEPS_RTC_ACTIVE && mp_active_timer == NULL)
+ {
+ drv_rtc_stop(p_instance);
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Function for processing user requests.
+ *
+ * Function is called only in the context of RTC interrupt.
+ */
+static void timer_req_process(drv_rtc_t const * const p_instance)
+{
+ nrf_atfifo_item_get_t fifo_ctx;
+ timer_req_t * p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
+
+ while (p_req)
+ {
+ switch (p_req->type)
+ {
+ case TIMER_REQ_START:
+ if (!p_req->p_timer->active)
+ {
+ p_req->p_timer->active = true;
+ if (p_req->p_timer->end_val - drv_rtc_counter_get(p_instance) > APP_TIMER_RTC_MAX_VALUE)
+ {
+ //A little trick to handle case when timer was scheduled just before overflow.
+ p_req->p_timer->end_val &= RTC_COUNTER_COUNTER_Msk;
+ }
+ nrf_sortlist_add(&m_app_timer_sortlist, &(p_req->p_timer->list_item));
+ NRF_LOG_INST_DEBUG(p_req->p_timer->p_log,"Start request (CC:%d).",
+ p_req->p_timer->end_val);
+ }
+ break;
+ case TIMER_REQ_STOP:
+ if (p_req->p_timer == mp_active_timer)
+ {
+ mp_active_timer = NULL;
+ }
+ UNUSED_RETURN_VALUE(nrf_sortlist_remove(&m_app_timer_sortlist, &(p_req->p_timer->list_item)));
+ NRF_LOG_INST_DEBUG(p_req->p_timer->p_log,"Stop request.");
+ break;
+ case TIMER_REQ_STOP_ALL:
+ sorted_list_stop_all();
+ m_global_active = true;
+ NRF_LOG_INFO("Stop all request.");
+ break;
+ default:
+ break;
+ }
+ UNUSED_RETURN_VALUE(nrf_atfifo_item_free(m_req_fifo, &fifo_ctx));
+ p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
+ }
+}
+
+static void rtc_irq(drv_rtc_t const * const p_instance)
+{
+ if (drv_rtc_overflow_pending(p_instance))
+ {
+ on_overflow_evt();
+ }
+ if (drv_rtc_compare_pending(p_instance, 0))
+ {
+ on_compare_evt();
+ }
+ timer_req_process(p_instance);
+ rtc_update(p_instance);
+}
+
+/**
+ * @brief Function for triggering processing user requests.
+ *
+ * @note All user requests are processed in a single context - RTC interrupt.
+ */
+static inline void timer_request_proc_trigger(void)
+{
+ drv_rtc_irq_trigger(&m_rtc_inst);
+}
+
+/**
+ * @brief Function for putting user request into the request queue
+ */
+static ret_code_t timer_req_schedule(app_timer_req_type_t type, app_timer_t * p_timer)
+{
+ nrf_atfifo_item_put_t fifo_ctx;
+ timer_req_t * p_req = nrf_atfifo_item_alloc(m_req_fifo, &fifo_ctx);
+
+ if (p_req)
+ {
+ p_req->type = type;
+ p_req->p_timer = p_timer;
+ if (nrf_atfifo_item_put(m_req_fifo, &fifo_ctx))
+ {
+ timer_request_proc_trigger();
+ }
+ else
+ {
+ NRF_LOG_WARNING("Scheduling interrupted another scheduling.");
+ }
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+}
+
+ret_code_t app_timer_init(void)
+{
+ ret_code_t err_code;
+ drv_rtc_config_t config = {
+ .prescaler = APP_TIMER_CONFIG_RTC_FREQUENCY,
+ .interrupt_priority = APP_TIMER_CONFIG_IRQ_PRIORITY
+ };
+
+ err_code = NRF_ATFIFO_INIT(m_req_fifo);
+ if (err_code != NRFX_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = drv_rtc_init(&m_rtc_inst, &config, rtc_irq);
+ if (err_code != NRFX_SUCCESS)
+ {
+ return err_code;
+ }
+ drv_rtc_overflow_enable(&m_rtc_inst, true);
+ if (APP_TIMER_KEEPS_RTC_ACTIVE)
+ {
+ drv_rtc_start(&m_rtc_inst);
+ }
+
+ m_global_active = true;
+ return err_code;
+}
+
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+ ASSERT(p_timer_id);
+ ASSERT(timeout_handler);
+
+ if (timeout_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_timer_t * p_t = (app_timer_t *) *p_timer_id;
+ p_t->handler = timeout_handler;
+ p_t->repeat_period = (mode == APP_TIMER_MODE_REPEATED) ? 1 : 0;
+ return NRF_SUCCESS;
+}
+
+ret_code_t app_timer_start(app_timer_t * p_timer, uint32_t timeout_ticks, void * p_context)
+{
+ ASSERT(p_timer);
+ app_timer_t * p_t = (app_timer_t *) p_timer;
+
+ if (timeout_ticks > APP_TIMER_RTC_MAX_VALUE)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ p_t->p_context = p_context;
+ p_t->end_val = drv_rtc_counter_get(&m_rtc_inst) + timeout_ticks;
+
+ if (p_t->repeat_period)
+ {
+ p_t->repeat_period = timeout_ticks;
+ }
+
+ return timer_req_schedule(TIMER_REQ_START, p_t);
+}
+
+
+ret_code_t app_timer_stop(app_timer_t * p_timer)
+{
+ ASSERT(p_timer);
+ app_timer_t * p_t = (app_timer_t *) p_timer;
+ p_t->active = false;
+
+ return timer_req_schedule(TIMER_REQ_STOP, p_t);
+}
+
+ret_code_t app_timer_stop_all(void)
+{
+ //block timer globally
+ m_global_active = false;
+
+ return timer_req_schedule(TIMER_REQ_STOP_ALL, NULL);
+}
+
+uint8_t app_timer_op_queue_utilization_get(void)
+{
+ /* Currently not supported by ATFIFO */
+ return 0;
+}
+
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from)
+{
+ return ((ticks_to - ticks_from) & RTC_COUNTER_COUNTER_Msk);
+}
+
+uint32_t app_timer_cnt_get(void)
+{
+ return drv_rtc_counter_get(&m_rtc_inst);
+}
+
+void app_timer_pause(void)
+{
+ drv_rtc_stop(&m_rtc_inst);
+}
+
+void app_timer_resume(void)
+{
+ drv_rtc_start(&m_rtc_inst);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c
new file mode 100644
index 0000000..8bda72d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c
@@ -0,0 +1,330 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <nrfx.h>
+#include <nrf_delay.h>
+#include <drv_rtc.h>
+
+/* Module is integral part of app_timer implementation. */
+#define NRF_LOG_MODULE_NAME app_timer
+#include <nrf_log.h>
+
+#define EVT_TO_STR(event) \
+ (event == NRF_RTC_EVENT_TICK ? "NRF_RTC_EVENT_TICK" : \
+ (event == NRF_RTC_EVENT_OVERFLOW ? "NRF_RTC_EVENT_OVERFLOW" : \
+ (event == NRF_RTC_EVENT_COMPARE_0 ? "NRF_RTC_EVENT_COMPARE_0" : \
+ (event == NRF_RTC_EVENT_COMPARE_1 ? "NRF_RTC_EVENT_COMPARE_1" : \
+ (event == NRF_RTC_EVENT_COMPARE_2 ? "NRF_RTC_EVENT_COMPARE_2" : \
+ (event == NRF_RTC_EVENT_COMPARE_3 ? "NRF_RTC_EVENT_COMPARE_3" : \
+ "UNKNOWN EVENT"))))))
+#if defined ( __ICCARM__ )
+/* IAR gives warning for offsetof with non-constant expression.*/
+#define CC_IDX_TO_CC_EVENT(_cc) \
+ ((nrf_rtc_event_t)(offsetof(NRF_RTC_Type, EVENTS_COMPARE[0]) + sizeof(uint32_t)*_cc))
+#else
+#define CC_IDX_TO_CC_EVENT(_cc) \
+ ((nrf_rtc_event_t)(offsetof(NRF_RTC_Type, EVENTS_COMPARE[_cc])))
+#endif
+
+/**@brief RTC driver instance control block structure. */
+typedef struct
+{
+ drv_rtc_t const * p_instance;
+ nrfx_drv_state_t state; /**< Instance state. */
+} drv_rtc_cb_t;
+
+// User callbacks local storage.
+static drv_rtc_handler_t m_handlers[DRV_RTC_ENABLED_COUNT];
+static drv_rtc_cb_t m_cb[DRV_RTC_ENABLED_COUNT];
+
+// According to Produce Specification RTC may not trigger COMPARE event if CC value set is equal to
+// COUNTER value or COUNTER+1.
+#define COUNTER_TO_CC_MIN_DISTANCE 2
+
+ret_code_t drv_rtc_init(drv_rtc_t const * const p_instance,
+ drv_rtc_config_t const * p_config,
+ drv_rtc_handler_t handler)
+{
+ ASSERT(p_instance);
+ ASSERT(p_config);
+ ASSERT(handler);
+
+ ret_code_t err_code;
+
+ m_handlers[p_instance->instance_id] = handler;
+
+ if (m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ NRF_LOG_WARNING("RTC instance already initialized.");
+ return err_code;
+ }
+
+ nrf_rtc_prescaler_set(p_instance->p_reg, p_config->prescaler);
+ NRFX_IRQ_PRIORITY_SET(p_instance->irq, p_config->interrupt_priority);
+ NRFX_IRQ_ENABLE(p_instance->irq);
+
+ m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_INITIALIZED;
+ m_cb[p_instance->instance_id].p_instance = p_instance;
+
+ err_code = NRF_SUCCESS;
+ NRF_LOG_INFO("RTC: initialized.");
+ return err_code;
+}
+
+void drv_rtc_uninit(drv_rtc_t const * const p_instance)
+{
+ ASSERT(p_instance);
+ uint32_t mask = NRF_RTC_INT_TICK_MASK |
+ NRF_RTC_INT_OVERFLOW_MASK |
+ NRF_RTC_INT_COMPARE0_MASK |
+ NRF_RTC_INT_COMPARE1_MASK |
+ NRF_RTC_INT_COMPARE2_MASK |
+ NRF_RTC_INT_COMPARE3_MASK;
+ ASSERT(m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ NRFX_IRQ_DISABLE(p_instance->irq);
+
+ drv_rtc_stop(p_instance);
+ nrf_rtc_event_disable(p_instance->p_reg, mask);
+ nrf_rtc_int_disable(p_instance->p_reg, mask);
+
+ m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_UNINITIALIZED;
+ NRF_LOG_INFO("RTC: Uninitialized.");
+}
+
+void drv_rtc_start(drv_rtc_t const * const p_instance)
+{
+ ASSERT(p_instance);
+ nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START);
+}
+
+void drv_rtc_stop(drv_rtc_t const * const p_instance)
+{
+ ASSERT(p_instance);
+ nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP);
+}
+
+void drv_rtc_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ bool irq_enable)
+{
+ ASSERT(p_instance);
+ nrf_rtc_int_t cc_int_mask = (nrf_rtc_int_t)(NRF_RTC_INT_COMPARE0_MASK << cc);
+ nrf_rtc_event_t cc_evt = CC_IDX_TO_CC_EVENT(cc);
+ abs_value &= RTC_COUNTER_COUNTER_Msk;
+
+ nrf_rtc_int_disable(p_instance->p_reg, cc_int_mask);
+ nrf_rtc_event_disable(p_instance->p_reg, cc_int_mask);
+ nrf_rtc_event_clear(p_instance->p_reg, cc_evt);
+ nrf_rtc_cc_set(p_instance->p_reg, cc,abs_value);
+ nrf_rtc_event_enable(p_instance->p_reg, cc_int_mask);
+
+ if (irq_enable)
+ {
+ nrf_rtc_int_enable(p_instance->p_reg, cc_int_mask);
+ }
+}
+
+ret_code_t drv_rtc_windowed_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ uint16_t safe_window)
+{
+ ASSERT(p_instance);
+ uint32_t prev_cc_set;
+ uint32_t counter;
+ nrf_rtc_int_t cc_int_mask = (nrf_rtc_int_t)(NRF_RTC_INT_COMPARE0_MASK << cc);
+ nrf_rtc_event_t cc_evt = CC_IDX_TO_CC_EVENT(cc);;
+ abs_value &=RTC_COUNTER_COUNTER_Msk;
+
+ nrf_rtc_int_disable(p_instance->p_reg, cc_int_mask);
+ nrf_rtc_event_disable(p_instance->p_reg, cc_int_mask);
+
+ nrf_rtc_event_clear(p_instance->p_reg, cc_evt);
+ prev_cc_set = nrf_rtc_cc_get(p_instance->p_reg, cc);
+
+ nrf_rtc_cc_set(p_instance->p_reg, cc,abs_value);
+ /* If prev CC setting equals or is just in front of the counter then there is a risk that before
+ * new CC will be set after enabling event previous CC will generate COMPARE event. In such risk
+ * delay must be introduced between writting CC value and enabling the event.
+ */
+ counter = nrf_rtc_counter_get(p_instance->p_reg);
+ if (((prev_cc_set - counter) & RTC_COUNTER_COUNTER_Msk) == 1)
+ {
+ NRF_LOG_DEBUG("RTC: Delay introduced due to risk of pre-firing.");
+ nrf_delay_us(33);
+ }
+ nrf_rtc_event_enable(p_instance->p_reg, cc_int_mask);
+
+ counter = nrf_rtc_counter_get(p_instance->p_reg);
+ int32_t diff = (int32_t)abs_value - (int32_t)counter;
+
+ diff &= RTC_COUNTER_COUNTER_Msk;
+ diff = (diff & 0x800000) ? (diff | 0xFF000000) : diff;
+
+ /* If diff shows that abs_value is after the counter or up to 2 ticks before then it is assumed
+ * that compare channel was set to late. It is based on a assumption that abs_value will never
+ * be set to value bigger than maximum counter value - safe window. */
+ if ((diff > (int32_t)(-safe_window)) && (diff <= COUNTER_TO_CC_MIN_DISTANCE))
+ {
+ //set CC to something back in time to prevent event triggering on next compare set.
+ NRF_LOG_DEBUG("RTC: Windowed compare set timeout (abs_value:%d, counter:%d).",
+ abs_value, counter);
+ return NRF_ERROR_TIMEOUT;
+ }
+ else
+ {
+ nrf_rtc_int_enable(p_instance->p_reg, cc_int_mask);
+ }
+ return NRF_SUCCESS;
+}
+
+static void evt_enable(drv_rtc_t const * const p_instance, uint32_t mask, bool irq_enable)
+{
+ ASSERT(p_instance);
+ nrf_rtc_event_enable(p_instance->p_reg, mask);
+ if (irq_enable)
+ {
+ nrf_rtc_int_enable(p_instance->p_reg, mask);
+ }
+}
+
+static void evt_disable(drv_rtc_t const * const p_instance, uint32_t mask)
+{
+ ASSERT(p_instance);
+ nrf_rtc_event_disable(p_instance->p_reg, mask);
+ nrf_rtc_int_disable(p_instance->p_reg, mask);
+}
+
+static bool evt_pending(drv_rtc_t const * const p_instance, nrf_rtc_event_t event)
+{
+ ASSERT(p_instance);
+ if (nrf_rtc_event_pending(p_instance->p_reg, event))
+ {
+ nrf_rtc_event_clear(p_instance->p_reg, event);
+ return true;
+ }
+ return false;
+}
+
+void drv_rtc_overflow_enable(drv_rtc_t const * const p_instance, bool irq_enable)
+{
+ evt_enable(p_instance, NRF_RTC_INT_OVERFLOW_MASK, irq_enable);
+}
+
+void drv_rtc_overflow_disable(drv_rtc_t const * const p_instance)
+{
+ evt_disable(p_instance, NRF_RTC_INT_OVERFLOW_MASK);
+}
+
+bool drv_rtc_overflow_pending(drv_rtc_t const * const p_instance)
+{
+ return evt_pending(p_instance, NRF_RTC_EVENT_OVERFLOW);
+}
+
+void drv_rtc_tick_enable(drv_rtc_t const * const p_instance, bool irq_enable)
+{
+ evt_enable(p_instance, NRF_RTC_INT_TICK_MASK, irq_enable);
+}
+
+void drv_rtc_tick_disable(drv_rtc_t const * const p_instance)
+{
+ evt_disable(p_instance, NRF_RTC_INT_TICK_MASK);
+}
+
+bool drv_rtc_tick_pending(drv_rtc_t const * const p_instance)
+{
+ return evt_pending(p_instance, NRF_RTC_EVENT_TICK);
+}
+
+void drv_rtc_compare_enable(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ bool irq_enable)
+{
+ evt_enable(p_instance, (uint32_t)NRF_RTC_INT_COMPARE0_MASK << cc, irq_enable);
+}
+
+void drv_rtc_compare_disable(drv_rtc_t const * const p_instance, uint32_t cc)
+{
+ evt_disable(p_instance, (uint32_t)NRF_RTC_INT_COMPARE0_MASK << cc);
+}
+
+bool drv_rtc_compare_pending(drv_rtc_t const * const p_instance, uint32_t cc)
+{
+ nrf_rtc_event_t cc_evt = CC_IDX_TO_CC_EVENT(cc);
+ return evt_pending(p_instance, cc_evt);
+}
+
+uint32_t drv_rtc_counter_get(drv_rtc_t const * const p_instance)
+{
+ return nrf_rtc_counter_get(p_instance->p_reg);
+}
+
+void drv_rtc_irq_trigger(drv_rtc_t const * const p_instance)
+{
+ NVIC_SetPendingIRQ(p_instance->irq);
+}
+
+#define drv_rtc_rtc_0_irq_handler RTC0_IRQHandler
+#define drv_rtc_rtc_1_irq_handler RTC1_IRQHandler
+#define drv_rtc_rtc_2_irq_handler RTC2_IRQHandler
+
+#if defined(APP_TIMER_V2_RTC0_ENABLED)
+void drv_rtc_rtc_0_irq_handler(void)
+{
+ m_handlers[DRV_RTC_RTC0_INST_IDX](m_cb[DRV_RTC_RTC0_INST_IDX].p_instance);
+}
+#endif
+
+#if defined(APP_TIMER_V2_RTC1_ENABLED)
+void drv_rtc_rtc_1_irq_handler(void)
+{
+ m_handlers[DRV_RTC_RTC1_INST_IDX](m_cb[DRV_RTC_RTC1_INST_IDX].p_instance);
+}
+#endif
+
+#if defined(APP_TIMER_V2_RTC2_ENABLED)
+void drv_rtc_rtc_2_irq_handler(void)
+{
+ m_handlers[DRV_RTC_RTC2_INST_IDX](m_cb[DRV_RTC_RTC2_INST_IDX].p_instance);
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h
new file mode 100644
index 0000000..3410460
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h
@@ -0,0 +1,304 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef DRV_RTC_H__
+#define DRV_RTC_H__
+
+#include <nrfx.h>
+#include <hal/nrf_rtc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup drv_rtc RTC driver
+ * @{
+ * @ingroup app_timer
+ * @brief Real Timer Counter (RTC) peripheral driver for app_timer.
+ */
+
+/** @brief Maximum RTC counter value. */
+#define DRV_RTC_MAX_CNT RTC_COUNTER_COUNTER_Msk
+
+/** @brief Time requires to update registers between RTC and MCU domains. */
+#define DRV_RTC_CONFIG_APPLY_TIME_US 33
+
+/**
+ * @brief Minimum delta value between set value and counter value.
+ *
+ * RTC peripheral requires two ticks to be sure that value it properly set in RTC value. Compare
+ * channel function requires additional one tick to avoid problematic situations (lack or additional
+ * unspecified event) when Compare Channel register is reseting or setting to N+2 value.
+ */
+#define DRV_RTC_MIN_TICK_HANDLED 3
+
+/** @brief Macro to convert microseconds into ticks. */
+#define DRV_RTC_US_TO_TICKS(us,freq) (us >= 2^17 ? \
+ ((((us)/1000)*(freq))/1000U) : (((us)*(freq))/1000000U) )
+
+
+/** @brief RTC driver instance structure. */
+typedef struct
+{
+ NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */
+ IRQn_Type irq; /**< Instance IRQ ID. */
+ uint8_t instance_id; /**< Instance index. */
+ uint8_t cc_channel_count; /**< Number of capture/compare channels. */
+} drv_rtc_t;
+
+/** @brief Macro for creating RTC driver instance.*/
+#define DRV_RTC_INSTANCE(id) \
+{ \
+ .p_reg = NRFX_CONCAT_2(NRF_RTC, id), \
+ .irq = NRFX_CONCAT_3(RTC, id, _IRQn), \
+ .instance_id = NRFX_CONCAT_3(DRV_RTC_RTC, id, _INST_IDX), \
+ .cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \
+}
+
+enum {
+#if defined(APP_TIMER_V2_RTC0_ENABLED)
+ DRV_RTC_RTC0_INST_IDX,
+#endif
+#if defined(APP_TIMER_V2_RTC1_ENABLED)
+ DRV_RTC_RTC1_INST_IDX,
+#endif
+#if defined(APP_TIMER_V2_RTC2_ENABLED)
+ DRV_RTC_RTC2_INST_IDX,
+#endif
+ DRV_RTC_ENABLED_COUNT
+};
+
+/** @brief RTC driver instance configuration structure. */
+typedef struct
+{
+ uint16_t prescaler; /**< Prescaler. */
+ uint8_t interrupt_priority; /**< Interrupt priority. */
+} drv_rtc_config_t;
+
+/** @brief RTC instance default configuration. */
+#define DRV_RTC_DEFAULT_CONFIG \
+{ \
+ .prescaler = RTC_FREQ_TO_PRESCALER(DRV_RTC_DEFAULT_CONFIG_FREQUENCY), \
+ .interrupt_priority = DRV_RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \
+}
+
+/** @brief RTC driver instance handler type. */
+typedef void (*drv_rtc_handler_t)(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for initializing the RTC driver instance.
+ *
+ * After initialization, the instance is in power off state. The LFCLK (@ref nrfx_clock)
+ * has to be started before using @ref drv_rtc.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_config Pointer to the structure with initial configuration.
+ * @param[in] handler Event handler provided by the user. Must not be NULL.
+ *
+ * @retval NRF_SUCCESS If successfully initialized.
+ * @retval NRF_ERROR_INVALID_STATE If the instance is already initialized.
+ */
+ret_code_t drv_rtc_init(drv_rtc_t const * const p_instance,
+ drv_rtc_config_t const * p_config,
+ drv_rtc_handler_t handler);
+
+/**
+ * @brief Function for uninitializing the RTC driver instance.
+ *
+ * After uninitialization, the instance is in idle state. The hardware should return to the state
+ * before initialization. The function asserts if the instance is in idle state.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_uninit(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for starting RTC clock.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_start(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for stopping RTC clock.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_stop(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for configuring compare channel.
+ *
+ * @note Function disables interrupts and only enable compare events. Remember to enable interrupt
+ * using @ref drv_rtc_compare_enable in case of using it.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ * @param[in] abs_value Absolute value to be set in the compare register.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ bool irq_enable);
+
+/**
+ * @brief Function for configuring compare channel with safe window.
+ *
+ * Maximum possible relative value is limited by safe window to detect
+ * cases when requested compare event has already occured.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ * @param[in] abs_value Absolute value to be set in the compare register.
+ * @param[in] safe_window Width of the safe window.
+ *
+ * @retval NRF_ERROR_TIMEOUT If @par abs_value is in safe window of event occured before
+ * enabling compare channel intterupt.
+ * @retval NRF_SUCCESS If successfully set.
+ */
+ret_code_t drv_rtc_windowed_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ uint16_t safe_window);
+
+/**
+ * @brief Function for enabling overflow event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_overflow_enable(drv_rtc_t const * const p_instance, bool irq_enable);
+
+/**
+ * @brief Function for diabling overflow event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_overflow_disable(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for checking if overflow event has occured.
+ *
+ * @note Event is cleared after reading.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return True if interrupt pending, false otherwise.
+ */
+bool drv_rtc_overflow_pending(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for enabling tick event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_tick_enable(drv_rtc_t const * const p_instance, bool irq_enable);
+
+/**
+ * @brief Function for disabling tick event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_tick_disable(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for checking if tick event has occured.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return True if interrupt pending, false otherwise.
+ */
+bool drv_rtc_tick_pending(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for enabling compare channel event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_compare_enable(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ bool irq_enable);
+
+/**
+ * @brief Function for disabling compare channel event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ */
+void drv_rtc_compare_disable(drv_rtc_t const * const p_instance, uint32_t cc);
+
+/**
+ * @brief Function for checking if compare channel event has occured.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ *
+ * @return True if interrupt pending, false otherwise.
+ */
+bool drv_rtc_compare_pending(drv_rtc_t const * const p_instance, uint32_t cc);
+
+/**
+ * @brief Function for getting current value of RTC counter.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return Counter value.
+ */
+uint32_t drv_rtc_counter_get(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for triggering RTC interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_irq_trigger(drv_rtc_t const * const p_instance);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DRV_RTC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c
new file mode 100644
index 0000000..56a14e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c
@@ -0,0 +1,366 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_TWI_MNGR)
+#include "nrf_twi_mngr.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+
+typedef volatile struct
+{
+ bool transaction_in_progress;
+ uint8_t transaction_result;
+} nrf_twi_mngr_cb_data_t;
+
+
+static ret_code_t start_transfer(nrf_twi_mngr_t const * p_nrf_twi_mngr)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ // Pointer for cleaner code.
+ nrf_twi_mngr_cb_t * p_cb = p_nrf_twi_mngr->p_nrf_twi_mngr_cb;
+
+ // [use a local variable to avoid using two volatile variables in one
+ // expression]
+ uint8_t current_transfer_idx = p_cb->current_transfer_idx;
+ nrf_twi_mngr_transfer_t const * p_transfer =
+ &p_cb->p_current_transaction->p_transfers[current_transfer_idx];
+ uint8_t address = NRF_TWI_MNGR_OP_ADDRESS(p_transfer->operation);
+
+ nrf_drv_twi_xfer_desc_t xfer_desc;
+ uint32_t flags;
+
+ xfer_desc.address = address;
+ xfer_desc.p_primary_buf = p_transfer->p_data;
+ xfer_desc.primary_length = p_transfer->length;
+
+ /* If it is possible try to bind two transfers together. They can be combined if:
+ * - there is no stop condition after current transfer.
+ * - current transfer is TX.
+ * - there is at least one more transfer in the transaction.
+ * - address of next transfer is the same as current transfer.
+ */
+ if ((p_transfer->flags & NRF_TWI_MNGR_NO_STOP) &&
+ !NRF_TWI_MNGR_IS_READ_OP(p_transfer->operation) &&
+ // Adding 1 to check if next transfer is from the same transaction.
+ ((current_transfer_idx + 1) < p_cb->p_current_transaction->number_of_transfers) &&
+ (NRF_TWI_MNGR_OP_ADDRESS(p_transfer->operation) ==
+ NRF_TWI_MNGR_OP_ADDRESS(p_cb->p_current_transaction->
+ p_transfers[current_transfer_idx + 1].operation)))
+ {
+ nrf_twi_mngr_transfer_t const * p_second_transfer =
+ &p_cb->p_current_transaction->p_transfers[current_transfer_idx + 1];
+ xfer_desc.p_secondary_buf = p_second_transfer->p_data;
+ xfer_desc.secondary_length = p_second_transfer->length;
+ xfer_desc.type = NRF_TWI_MNGR_IS_READ_OP(p_second_transfer->operation) ?
+ NRF_DRV_TWI_XFER_TXRX : NRF_DRV_TWI_XFER_TXTX;
+ flags = (p_second_transfer->flags & NRF_TWI_MNGR_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0;
+ p_cb->current_transfer_idx++;
+ }
+ else
+ {
+ xfer_desc.type = NRF_TWI_MNGR_IS_READ_OP(p_transfer->operation) ? NRF_DRV_TWI_XFER_RX :
+ NRF_DRV_TWI_XFER_TX;
+ xfer_desc.p_secondary_buf = NULL;
+ xfer_desc.secondary_length = 0;
+ flags = (p_transfer->flags & NRF_TWI_MNGR_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0;
+ }
+
+ return nrf_drv_twi_xfer(&p_nrf_twi_mngr->twi, &xfer_desc, flags);
+}
+
+
+static void transaction_end_signal(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ ret_code_t result)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ if (p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->callback)
+ {
+ // [use a local variable to avoid using two volatile variables in one
+ // expression]
+ void * p_user_data = p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->p_user_data;
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->callback(result, p_user_data);
+ }
+}
+
+static void twi_event_handler(nrf_drv_twi_evt_t const * p_event,
+ void * p_context);
+
+// This function starts pending transaction if there is no current one or
+// when 'switch_transaction' parameter is set to true. It is important to
+// switch to new transaction without setting 'p_nrf_twi_mngr->p_current_transaction'
+// to NULL in between, since this pointer is used to check idle status - see
+// 'nrf_twi_mngr_is_idle()'.
+static void start_pending_transaction(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ bool switch_transaction)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ // Pointer for cleaner code.
+ nrf_twi_mngr_cb_t * p_cb = p_nrf_twi_mngr->p_nrf_twi_mngr_cb;
+
+ for (;;)
+ {
+ bool start_transaction = false;
+
+ CRITICAL_REGION_ENTER();
+ if (switch_transaction || nrf_twi_mngr_is_idle(p_nrf_twi_mngr))
+ {
+ if (nrf_queue_pop(p_nrf_twi_mngr->p_queue, (void *)(&p_cb->p_current_transaction))
+ == NRF_SUCCESS)
+ {
+ start_transaction = true;
+ }
+ else
+ {
+ p_cb->p_current_transaction = NULL;
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (!start_transaction)
+ {
+ return;
+ }
+ else
+ {
+ ret_code_t result;
+
+ nrf_drv_twi_config_t const * p_instance_cfg =
+ p_cb->p_current_transaction->p_required_twi_cfg == NULL ?
+ &p_cb->default_configuration :
+ p_cb->p_current_transaction->p_required_twi_cfg;
+
+ if (memcmp(p_cb->p_current_configuration, p_instance_cfg, sizeof(*p_instance_cfg)) != 0)
+ {
+ ret_code_t err_code;
+ nrf_drv_twi_uninit(&p_nrf_twi_mngr->twi);
+ err_code = nrf_drv_twi_init(&p_nrf_twi_mngr->twi,
+ p_instance_cfg,
+ twi_event_handler,
+ (void *)p_nrf_twi_mngr);
+ ASSERT(err_code == NRF_SUCCESS);
+ nrf_drv_twi_enable(&p_nrf_twi_mngr->twi);
+ UNUSED_VARIABLE(err_code);
+ p_cb->p_current_configuration = p_instance_cfg;
+ }
+
+ // Try to start first transfer for this new transaction.
+ p_cb->current_transfer_idx = 0;
+ result = start_transfer(p_nrf_twi_mngr);
+
+ // If transaction started successfully there is nothing more to do here now.
+ if (result == NRF_SUCCESS)
+ {
+ return;
+ }
+
+ // Transfer failed to start - notify user that this transaction
+ // cannot be started and try with next one (in next iteration of
+ // the loop).
+ transaction_end_signal(p_nrf_twi_mngr, result);
+
+ switch_transaction = true;
+ }
+ }
+}
+
+
+static void twi_event_handler(nrf_drv_twi_evt_t const * p_event,
+ void * p_context)
+{
+ ASSERT(p_event != NULL);
+
+ nrf_twi_mngr_t * p_nrf_twi_mngr = (nrf_twi_mngr_t *)p_context;
+ ret_code_t result;
+
+ // This callback should be called only during transaction.
+ ASSERT(p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction != NULL);
+
+ if (p_event->type == NRF_DRV_TWI_EVT_DONE)
+ {
+ result = NRF_SUCCESS;
+
+ // Transfer finished successfully. If there is another one to be
+ // performed in the current transaction, start it now.
+ // [use a local variable to avoid using two volatile variables in one
+ // expression]
+ uint8_t current_transfer_idx = p_nrf_twi_mngr->p_nrf_twi_mngr_cb->current_transfer_idx;
+ ++current_transfer_idx;
+ if (current_transfer_idx <
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->number_of_transfers)
+ {
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->current_transfer_idx = current_transfer_idx;
+
+ result = start_transfer(p_nrf_twi_mngr);
+
+ if (result == NRF_SUCCESS)
+ {
+ // The current transaction goes on and we've successfully
+ // started its next transfer -> there is nothing more to do.
+ return;
+ }
+
+ // [if the next transfer could not be started due to some error
+ // we finish the transaction with this error code as the result]
+ }
+ }
+ else
+ {
+ result = NRF_ERROR_INTERNAL;
+ }
+
+ // The current transaction has been completed or interrupted by some error.
+ // Notify the user and start next one (if there is any).
+ transaction_end_signal(p_nrf_twi_mngr, result);
+ // [we switch transactions here ('p_nrf_twi_mngr->p_current_transaction' is set
+ // to NULL only if there is nothing more to do) in order to not generate
+ // spurious idle status (even for a moment)]
+ start_pending_transaction(p_nrf_twi_mngr, true);
+}
+
+
+ret_code_t nrf_twi_mngr_init(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_default_twi_config)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+ ASSERT(p_nrf_twi_mngr->p_queue != NULL);
+ ASSERT(p_nrf_twi_mngr->p_queue->size > 0);
+ ASSERT(p_default_twi_config != NULL);
+
+ ret_code_t err_code;
+
+ err_code = nrf_drv_twi_init(&p_nrf_twi_mngr->twi,
+ p_default_twi_config,
+ twi_event_handler,
+ (void *)p_nrf_twi_mngr);
+ VERIFY_SUCCESS(err_code);
+
+ nrf_drv_twi_enable(&p_nrf_twi_mngr->twi);
+
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction = NULL;
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->default_configuration = *p_default_twi_config;
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_configuration =
+ &p_nrf_twi_mngr->p_nrf_twi_mngr_cb->default_configuration;
+
+ return NRF_SUCCESS;
+}
+
+
+void nrf_twi_mngr_uninit(nrf_twi_mngr_t const * p_nrf_twi_mngr)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ nrf_drv_twi_uninit(&p_nrf_twi_mngr->twi);
+
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction = NULL;
+}
+
+
+ret_code_t nrf_twi_mngr_schedule(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_twi_mngr_transaction_t const * p_transaction)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+ ASSERT(p_transaction != NULL);
+ ASSERT(p_transaction->p_transfers != NULL);
+ ASSERT(p_transaction->number_of_transfers != 0);
+
+ ret_code_t result = NRF_SUCCESS;
+
+ result = nrf_queue_push(p_nrf_twi_mngr->p_queue, (void *)(&p_transaction));
+ if (result == NRF_SUCCESS)
+ {
+ // New transaction has been successfully added to queue,
+ // so if we are currently idle it's time to start the job.
+ start_pending_transaction(p_nrf_twi_mngr, false);
+ }
+
+ return result;
+}
+
+
+static void internal_transaction_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_twi_mngr_cb_data_t *p_cb_data = (nrf_twi_mngr_cb_data_t *)p_user_data;
+
+ p_cb_data->transaction_result = result;
+ p_cb_data->transaction_in_progress = false;
+}
+
+
+ret_code_t nrf_twi_mngr_perform(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_config,
+ nrf_twi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void))
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+ ASSERT(p_transfers != NULL);
+ ASSERT(number_of_transfers != 0);
+
+ nrf_twi_mngr_cb_data_t cb_data =
+ {
+ .transaction_in_progress = true
+ };
+
+ nrf_twi_mngr_transaction_t internal_transaction =
+ {
+ .callback = internal_transaction_cb,
+ .p_user_data = (void *)&cb_data,
+ .p_transfers = p_transfers,
+ .number_of_transfers = number_of_transfers,
+ .p_required_twi_cfg = p_config
+ };
+
+ ret_code_t result = nrf_twi_mngr_schedule(p_nrf_twi_mngr, &internal_transaction);
+ VERIFY_SUCCESS(result);
+
+ while (cb_data.transaction_in_progress)
+ {
+ if (user_function)
+ {
+ user_function();
+ }
+ }
+
+ return cb_data.transaction_result;
+}
+#endif //NRF_MODULE_ENABLED(NRF_TWI_MNGR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h
new file mode 100644
index 0000000..a63803a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h
@@ -0,0 +1,342 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_TWI_MNGR_H__
+#define NRF_TWI_MNGR_H__
+
+#include <stdint.h>
+#include "nrf_drv_twi.h"
+#include "sdk_errors.h"
+#include "nrf_queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_twi_mngr TWI transaction manager
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for scheduling TWI transactions.
+ */
+
+//If TWIM is present buffers can only be in RAM
+/*lint -save -e491*/
+
+/**
+ * @brief Macro checking if buffers should be stored in RAM.
+ */
+#ifndef NRF_TWI_MNGR_BUFFERS_IN_RAM
+ #define NRF_TWI_MNGR_BUFFERS_IN_RAM defined(TWIM_PRESENT)
+#endif
+
+/**
+ * @brief Modifier used in array declaration for TWI Manager.
+ *
+ * @note For TWI peripheral array can be const, for TWIM array has to be located in RAM.
+ */
+#if NRF_TWI_MNGR_BUFFERS_IN_RAM
+ #define NRF_TWI_MNGR_BUFFER_LOC_IND
+#else
+ #define NRF_TWI_MNGR_BUFFER_LOC_IND const
+#endif
+/*lint -restore*/
+
+/**
+ * @brief Flag indicating that a given transfer should not be ended
+ * with a stop condition.
+ *
+ * Use this flag when a stop condition is undesirable between two transfers,
+ * for example, when the first transfer is a write that sets an address in the slave
+ * device and the second one is a read that fetches certain data using this
+ * address. In this case, the second transfer should follow directly after the
+ * first transfer, with a repeated start condition instead of a stop and then
+ * a new start condition.
+ */
+#define NRF_TWI_MNGR_NO_STOP 0x01
+
+/**
+ * @brief Macro for creating a write transfer.
+ *
+ * @param[in] address Slave address.
+ * @param[in] p_data Pointer to the data to be sent.
+ * @param[in] length Number of bytes to transfer.
+ * @param[in] flags Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
+ */
+#define NRF_TWI_MNGR_WRITE(address, p_data, length, flags) \
+ NRF_TWI_MNGR_TRANSFER(NRF_TWI_MNGR_WRITE_OP(address), p_data, length, flags)
+
+/**
+ * @brief Macro for creating a read transfer.
+ *
+ * @param address Slave address.
+ * @param[in] p_data Pointer to the buffer where received data should be placed.
+ * @param length Number of bytes to transfer.
+ * @param flags Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
+ */
+#define NRF_TWI_MNGR_READ(address, p_data, length, flags) \
+ NRF_TWI_MNGR_TRANSFER(NRF_TWI_MNGR_READ_OP(address), p_data, length, flags)
+
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_TRANSFER(_operation, _p_data, _length, _flags) \
+{ \
+ .p_data = (uint8_t *)(_p_data), \
+ .length = _length, \
+ .operation = _operation, \
+ .flags = _flags \
+}
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_WRITE_OP(address) (((address) << 1) | 0)
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_READ_OP(address) (((address) << 1) | 1)
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_IS_READ_OP(operation) ((operation) & 1)
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_OP_ADDRESS(operation) ((operation) >> 1)
+
+/**
+ * @brief TWI transaction callback prototype.
+ *
+ * @param result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_user_data Pointer to user data defined in transaction
+ * descriptor.
+ */
+typedef void (* nrf_twi_mngr_callback_t)(ret_code_t result, void * p_user_data);
+
+/**
+ * @brief TWI transfer descriptor.
+ */
+typedef struct {
+ uint8_t * p_data; ///< Pointer to the buffer holding the data.
+ uint8_t length; ///< Number of bytes to transfer.
+ uint8_t operation; ///< Device address combined with transfer direction.
+ uint8_t flags; ///< Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
+} nrf_twi_mngr_transfer_t;
+
+/**
+ * @brief TWI transaction descriptor.
+ */
+typedef struct {
+ nrf_twi_mngr_callback_t callback;
+ ///< User-specified function to be called after the transaction is finished.
+
+ void * p_user_data;
+ ///< Pointer to user data to be passed to the callback.
+
+ nrf_twi_mngr_transfer_t const * p_transfers;
+ ///< Pointer to the array of transfers that make up the transaction.
+
+ uint8_t number_of_transfers;
+ ///< Number of transfers that make up the transaction.
+
+ nrf_drv_twi_config_t const * p_required_twi_cfg;
+ ///< Pointer to instance hardware configuration.
+} nrf_twi_mngr_transaction_t;
+
+/**
+ * @brief TWI instance control block.
+ */
+typedef struct {
+ nrf_twi_mngr_transaction_t const * volatile p_current_transaction;
+ ///< Currently realized transaction.
+
+ nrf_drv_twi_config_t default_configuration;
+ ///< Default hardware configuration.
+
+ nrf_drv_twi_config_t const * p_current_configuration;
+ ///< Pointer to current hardware configuration.
+
+ uint8_t volatile current_transfer_idx;
+ ///< Index of currently performed transfer (within current transaction).
+} nrf_twi_mngr_cb_t;
+
+/**
+ * @brief TWI transaction manager instance.
+ */
+typedef struct {
+ nrf_twi_mngr_cb_t * p_nrf_twi_mngr_cb;
+ ///< Control block of instance.
+
+ nrf_queue_t const * p_queue;
+ ///< Transaction queue.
+
+ nrf_drv_twi_t twi;
+ ///< Pointer to TWI master driver instance.
+} nrf_twi_mngr_t;
+
+/**
+ * @brief Macro that simplifies defining a TWI transaction manager
+ * instance.
+ *
+ * This macro allocates a static buffer for the transaction queue.
+ * Therefore, it should be used in only one place in the code for a given
+ * instance.
+ *
+ * @note The queue size is the maximum number of pending transactions
+ * not counting the one that is currently realized. This means that
+ * for an empty queue with size of, for example, 4 elements, it is
+ * possible to schedule up to 5 transactions.
+ *
+ * @param[in] _nrf_twi_mngr_name Name of instance to be created.
+ * @param[in] _queue_size Size of the transaction queue (maximum number
+ * of pending transactions).
+ * @param[in] _twi_idx Index of hardware TWI instance to be used.
+ */
+#define NRF_TWI_MNGR_DEF(_nrf_twi_mngr_name, _queue_size, _twi_idx) \
+ NRF_QUEUE_DEF(nrf_twi_mngr_transaction_t const *, \
+ _nrf_twi_mngr_name##_queue, \
+ (_queue_size), \
+ NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static nrf_twi_mngr_cb_t CONCAT_2(_nrf_twi_mngr_name, _cb); \
+ static const nrf_twi_mngr_t _nrf_twi_mngr_name = \
+ { \
+ .p_nrf_twi_mngr_cb = &CONCAT_2(_nrf_twi_mngr_name, _cb), \
+ .p_queue = &_nrf_twi_mngr_name##_queue, \
+ .twi = NRF_DRV_TWI_INSTANCE(_twi_idx) \
+ }
+
+/**
+ * @brief Function for initializing a TWI transaction manager instance.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the instance to be initialized.
+ * @param[in] p_default_twi_config Pointer to the TWI master driver configuration. This configuration
+ * will be used whenever the scheduled transaction will have
+ * p_twi_configuration set to NULL value.
+ *
+ * @return Values returned by the @ref nrf_drv_twi_init function.
+ */
+ret_code_t nrf_twi_mngr_init(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_default_twi_config);
+
+/**
+ * @brief Function for uninitializing a TWI transaction manager instance.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the instance to be uninitialized.
+ */
+void nrf_twi_mngr_uninit(nrf_twi_mngr_t const * p_nrf_twi_mngr);
+
+/**
+ * @brief Function for scheduling a TWI transaction.
+ *
+ * The transaction is enqueued and started as soon as the TWI bus is
+ * available, thus when all previously scheduled transactions have been
+ * finished (possibly immediately).
+ *
+ * @note If @ref nrf_twi_mngr_transaction_t::p_required_twi_cfg
+ * is set to a non-NULL value the module will compare it with
+ * @ref nrf_twi_mngr_cb_t::p_current_configuration and reinitialize hardware
+ * TWI instance with new parameters if any differences are found.
+ * If @ref nrf_twi_mngr_transaction_t::p_required_twi_cfg is set to NULL then
+ * it will treat it as it would be set to @ref nrf_twi_mngr_cb_t::default_configuration.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the TWI transaction manager instance.
+ * @param[in] p_transaction Pointer to the descriptor of the transaction to be
+ * scheduled.
+ *
+ * @retval NRF_SUCCESS If the transaction has been successfully scheduled.
+ * @retval NRF_ERROR_NO_MEM If the queue is full (Only if queue in
+ * @ref NRF_QUEUE_MODE_NO_OVERFLOW).
+ */
+ret_code_t nrf_twi_mngr_schedule(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_twi_mngr_transaction_t const * p_transaction);
+
+/**
+ * @brief Function for scheduling a transaction and waiting until it is finished.
+ *
+ * This function schedules a transaction that consists of one or more transfers
+ * and waits until it is finished.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the TWI transaction manager instance.
+ * @param[in] p_config Required TWI configuration.
+ * @param[in] p_transfers Pointer to an array of transfers to be performed.
+ * @param number_of_transfers Number of transfers to be performed.
+ * @param user_function User-specified function to be called while
+ * waiting. NULL if such functionality
+ * is not needed.
+ *
+ * @retval NRF_SUCCESS If the transfers have been successfully realized.
+ * @retval NRF_ERROR_BUSY If some transfers are already being performed.
+ * @retval - Other error codes mean that the transaction has ended
+ * with the error that is specified in the error code.
+ */
+ret_code_t nrf_twi_mngr_perform(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_config,
+ nrf_twi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void));
+
+/**
+ * @brief Function for getting the current state of a TWI transaction manager
+ * instance.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the TWI transaction manager instance.
+ *
+ * @retval true If all scheduled transactions have been finished.
+ * @retval false Otherwise.
+ */
+__STATIC_INLINE bool nrf_twi_mngr_is_idle(nrf_twi_mngr_t const * p_nrf_twi_mngr);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE bool nrf_twi_mngr_is_idle(nrf_twi_mngr_t const * p_nrf_twi_mngr)
+{
+ return (p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction == NULL);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+/**
+ *@}
+ **/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_TWI_MNGR_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c
new file mode 100644
index 0000000..9c080bc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_twi_sensor.h"
+#include <string.h>
+
+#define NRF_LOG_MODULE_NAME twi_sensor
+#if NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_TWI_SENSOR_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_TWI_SENSOR_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+ret_code_t nrf_twi_sensor_init(nrf_twi_sensor_t * p_twi_sensor)
+{
+ return nrf_balloc_init(p_twi_sensor->p_pool);
+}
+
+static void sensor_read_reg_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_twi_sensor_read_cmd_t * p_cmd = &((nrf_twi_sensor_cmd_t *) p_user_data)->read;
+ NRF_LOG_INFO("Read cb reg addr: 0x%02X, result %d", p_cmd->reg_address, result);
+ NRF_LOG_DEBUG("\r\nCallback pointer: %p\r\nData:", p_cmd->user_cb);
+ NRF_LOG_HEXDUMP_DEBUG(p_cmd->transfers[1].p_data, p_cmd->transfers[1].length);
+
+ if (p_cmd->user_cb != NULL)
+ {
+ p_cmd->user_cb(result, (void*)p_cmd->transfers[1].p_data);
+ }
+ nrf_balloc_free(p_cmd->p_instance->p_pool, p_user_data);
+}
+
+ret_code_t nrf_twi_sensor_reg_read(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data,
+ uint8_t length)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ NRF_LOG_INFO("Sensor addr: 0x%02X"
+ "\r\nRead reg addr: 0x%02X, bytes %d",
+ sensor_addr,
+ reg_address,
+ length);
+
+ nrf_twi_sensor_read_cmd_t * p_cmd =
+ (nrf_twi_sensor_read_cmd_t *) nrf_balloc_alloc(p_instance->p_pool);
+ if (p_cmd == NULL)
+ {
+ NRF_LOG_WARNING("Memory not allocated.");
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_cmd->p_instance = p_instance;
+ p_cmd->user_cb = user_cb;
+ p_cmd->reg_address = reg_address;
+
+ p_cmd->transfers[0] = (nrf_twi_mngr_transfer_t) NRF_TWI_MNGR_WRITE(sensor_addr,
+ &p_cmd->reg_address,
+ 1,
+ NRF_TWI_MNGR_NO_STOP);
+
+ p_cmd->transfers[1] = (nrf_twi_mngr_transfer_t) NRF_TWI_MNGR_READ(sensor_addr,
+ p_data,
+ length,
+ NRF_TWI_MNGR_NO_STOP);
+
+ p_cmd->transaction = (nrf_twi_mngr_transaction_t) {
+ .callback = sensor_read_reg_cb,
+ .p_user_data = p_cmd,
+ .p_transfers = p_cmd->transfers,
+ .number_of_transfers = ARRAY_SIZE(p_cmd->transfers)
+ };
+
+ ret_code_t err_code = nrf_twi_mngr_schedule(p_instance->p_twi_mngr, &p_cmd->transaction);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Transaction not scheduled.\r\nSensor addr: 0x%02X Error code: %d",
+ sensor_addr,
+ err_code);
+ nrf_balloc_free(p_instance->p_pool, p_cmd);
+ }
+ return err_code;
+}
+
+static void sensor_write_reg_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_twi_sensor_write_cmd_t * p_cmd = &((nrf_twi_sensor_cmd_t *) p_user_data)->write;
+ NRF_LOG_INFO("Write cb reg addr: 0x%02X, result %d", p_cmd->send_msg[0], result);
+ nrf_balloc_free(p_cmd->p_instance->p_pool, p_user_data);
+}
+
+ret_code_t nrf_twi_sensor_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t const * p_data,
+ uint8_t length,
+ bool copy_flag)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ NRF_LOG_INFO("Sensor addr: 0x%02X Write length %d", sensor_addr, length);
+ NRF_LOG_DEBUG("Data: ");
+ NRF_LOG_HEXDUMP_DEBUG(p_data, length);
+ nrf_twi_sensor_write_cmd_t * p_cmd =
+ (nrf_twi_sensor_write_cmd_t *) nrf_balloc_alloc(p_instance->p_pool);
+ if (p_cmd == NULL)
+ {
+ NRF_LOG_WARNING("Memory not allocated. Sensor addr: 0x%02X",
+ sensor_addr);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_cmd->p_instance = p_instance;
+
+ p_cmd->transfer = (nrf_twi_mngr_transfer_t) NRF_TWI_MNGR_WRITE(sensor_addr,
+ p_data,
+ length,
+ 0);
+
+ if (copy_flag == true)
+ {
+ if (length > NRF_TWI_SENSOR_SEND_BUF_SIZE)
+ {
+ NRF_LOG_ERROR("Data too long to copy. Sensor addr: 0x%02X"
+ "\r\nRequested write length: %d, max length: %d",
+ sensor_addr,
+ length,
+ NRF_TWI_SENSOR_SEND_BUF_SIZE);
+ nrf_balloc_free(p_instance->p_pool, p_cmd);
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ memcpy(p_cmd->send_msg, p_data, length);
+ p_cmd->transfer.p_data = p_cmd->send_msg;
+ }
+
+ p_cmd->transaction = (nrf_twi_mngr_transaction_t) {
+ .callback = sensor_write_reg_cb,
+ .p_user_data = p_cmd,
+ .p_transfers = &p_cmd->transfer,
+ .number_of_transfers = 1
+ };
+
+ ret_code_t err_code = nrf_twi_mngr_schedule(p_instance->p_twi_mngr, &p_cmd->transaction);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Transaction not scheduled.\r\nSensor addr: 0x%02X Error code: %d",
+ sensor_addr,
+ err_code);
+ nrf_balloc_free(p_instance->p_pool, p_cmd);
+ }
+ return err_code;
+}
+
+ret_code_t nrf_twi_sensor_reg_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ uint8_t * p_data,
+ uint8_t length)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ NRF_LOG_INFO("Write register: 0x%02X", reg_address);
+ if (length > NRF_TWI_SENSOR_SEND_BUF_SIZE - 1) // Subtracting one byte for address
+ {
+ NRF_LOG_ERROR("Data too long to copy. Sensor addr: 0x%02X"
+ "\r\nRequested write length: %d, max length: %d",
+ sensor_addr,
+ length,
+ NRF_TWI_SENSOR_SEND_BUF_SIZE - 1);
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ uint8_t buf[NRF_TWI_SENSOR_SEND_BUF_SIZE];
+
+ buf[0] = reg_address;
+ memcpy(&buf[1], p_data, length);
+ return nrf_twi_sensor_write(p_instance, sensor_addr, buf, length + 1, true);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h
new file mode 100644
index 0000000..adddff2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h
@@ -0,0 +1,314 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**@file
+ *
+ * @defgroup nrf_twi_sensor TWI Sensor module.
+ * @{
+ * @ingroup app_common
+ */
+
+#ifndef NRF_TWI_SENSOR_H
+#define NRF_TWI_SENSOR_H
+
+#include "nrf_twi_mngr.h"
+#include "nrf_balloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Internal write operation buffer length.
+ *
+ * Defines how many bytes can be stored internally.
+ * 16 bytes were selected so that nrf_twi_sensor_write_cmd_t size
+ * matches nrf_twi_sensor_read_cmd_t size.
+ */
+#define NRF_TWI_SENSOR_SEND_BUF_SIZE 16
+
+/**
+ * @brief Register read callback prototype.
+ *
+ * @param[in] result Return error code from TWI manager and underlying drivers.
+ * @param[in] p_register_data Pointer to register value.
+ */
+typedef void (* nrf_twi_sensor_reg_cb_t)(ret_code_t result, void * p_register_data);
+
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_mngr_t const * const p_twi_mngr;
+ nrf_balloc_t const * const p_pool;
+
+
+} nrf_twi_sensor_t;
+
+/**
+ * @brief Struct describing sensor read command.
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ uint8_t reg_address;
+ nrf_twi_mngr_transfer_t transfers[2];
+ nrf_twi_mngr_transaction_t transaction;
+ nrf_twi_sensor_reg_cb_t user_cb;
+ nrf_twi_sensor_t const * p_instance;
+} nrf_twi_sensor_read_cmd_t;
+
+/**
+ * @brief Struct describing sensor write command.
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ uint8_t send_msg[NRF_TWI_SENSOR_SEND_BUF_SIZE];
+ nrf_twi_mngr_transfer_t transfer;
+ nrf_twi_mngr_transaction_t transaction;
+ nrf_twi_sensor_t const * p_instance;
+} nrf_twi_sensor_write_cmd_t;
+
+/**
+ * @brief Union for sensor commands. Needed in buffer definition.
+ *
+ * @note For internal use only.
+ */
+typedef union
+{
+ nrf_twi_sensor_read_cmd_t read;
+ nrf_twi_sensor_write_cmd_t write;
+} nrf_twi_sensor_cmd_t;
+
+
+/**
+ * @brief Macro creating common twi sensor instance.
+ *
+ * Data in structure is used for basic communication with sensors.
+ * THere should be one instance per TWI bus.
+ *
+ * @param[in] twi_sensor_name TWI common sensor instance name.
+ * @param[in] p_nrf_twi_mngr Pointer to TWI Manager instance. @ref NRF_TWI_MNGR_DEF
+ * @param[in] msg_buff_size Size of buffer used in communication
+ *
+ * @note Buffer size should be less or equal to TWI manager queue size.
+ * Minimum buffer size can be found after checking utilization of sensor buffer.
+ */
+#define NRF_TWI_SENSOR_DEF(twi_sensor_name, p_nrf_twi_mngr, msg_buff_size) \
+ NRF_BALLOC_DEF(CONCAT_2(twi_sensor_name,_pool), sizeof(nrf_twi_sensor_cmd_t), msg_buff_size);\
+ static nrf_twi_sensor_t twi_sensor_name = \
+ { \
+ .p_twi_mngr = p_nrf_twi_mngr, \
+ .p_pool = &CONCAT_2(twi_sensor_name,_pool) \
+ }
+
+/**
+ * @brief Macro for defining TWI manager read transfer.
+ *
+ * @note For internal use only.
+ */
+#define NRF_TWI_SENSOR_READ(p_reg_addr, p_buffer, byte_cnt) \
+ NRF_TWI_MNGR_WRITE(0x00, p_reg_addr, 1, NRF_TWI_MNGR_NO_STOP), \
+ NRF_TWI_MNGR_READ (0x00, p_buffer, byte_cnt, 0)
+
+/**
+ * @brief Macro for defining TWI manager write transfer.
+ *
+ * @note For internal use only.
+ */
+#define NRF_TWI_SENSOR_WRITE(p_buffer, byte_cnt) \
+ NRF_TWI_MNGR_WRITE(0x00, p_buffer, byte_cnt, 0)
+
+
+/**
+ * @brief Macro for assigning sensor address to transfers.
+ *
+ * @param[in] _transfers Transfers array.
+ * @param[in] _sensor_addr Desired sensor address.
+ *
+ * @note For internal use only.
+ */
+#define NRF_TWI_SENSOR_ADDRESS_SET(_transfers, _sensor_addr) \
+ for (uint8_t i = 0; i < ARRAY_SIZE(_transfers); i++) \
+ { \
+ if (i % 2 == 0) \
+ { \
+ transfers[i].operation = NRF_TWI_MNGR_WRITE_OP(_sensor_addr); \
+ } \
+ else \
+ { \
+ transfers[i].operation = NRF_TWI_MNGR_READ_OP(_sensor_addr); \
+ } \
+ }
+
+/**
+ * @brief Macro for setting parameters in sensor register.
+ *
+ * @param[in,out] _register Register to be altered.
+ * @param[in] _msk Parameter mask.
+ * @param[in] _pos Parameter position.
+ * @param[in] _val Parameter value to be set.
+ */
+#define NRF_TWI_SENSOR_REG_SET(_register, _msk, _pos, _val) \
+ _register &= ~(_msk); \
+ _register |= ((_msk) & ((_val) << (_pos)))
+
+
+/**
+ * @brief Macro for getting parameters from sensor register.
+ *
+ * @param[in] _register Register to be processed.
+ * @param[in] _msk Parameter mask.
+ * @param[in] _pos Parameter position.
+ *
+ * @note For usage with registers read using nrf_twi_sensor_register_read function.
+ *
+ * @return Parameter value
+ */
+#define NRF_TWI_SENSOR_REG_VAL_GET(_register, _msk, _pos) \
+ (((_register) & (_msk)) >> (_pos))
+
+/**
+ * @brief Function for initialization of sensor common instance.
+ *
+ * @note TWI Manager should be initialized before @ref nrf_twi_mngr_init
+ * @param[in] p_twi_sensor Pointer to sensor common instance.
+ *
+ * @return Error code from nrf_balloc @ref nrf_balloc_init
+ */
+ret_code_t nrf_twi_sensor_init(nrf_twi_sensor_t * p_twi_sensor);
+
+/**
+ * @brief Function for reading sensor register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] sensor_addr Sensor address.
+ * @param[in] reg_address Register address.
+ * @param[in] user_cb User callback.
+ * @param[out] p_data Pointer to data save location.
+ * @param[in] length Number of bytes to read.
+ *
+ * @retval NRF_ERROR_NO_MEM If there is no memory in sensor buffer
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval other Error code from TWI manager @ref nrf_twi_mngr_schedule.
+ */
+ret_code_t nrf_twi_sensor_reg_read(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data,
+ uint8_t length);
+
+/**
+ * @brief Function for writing to sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] sensor_addr Sensor address.
+ * @param[in] p_data Pointer to data to be written.
+ * @param[in] length Number of bytes to write.
+ * @param[in] copy_flag If true, p_data is copied into internal static buffer.
+ *
+ * @note Most of the time, to write to sensors register, first byte in p_data has to be
+ * register address.
+ *
+ * @retval NRF_ERROR_NO_MEM If there is no memory in sensor buffer
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to copy more bytes than
+ * NRF_TWI_SENSOR_SEND_BUF_SIZE.
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval other Error code from TWI manager @ref nrf_twi_mngr_schedule.
+ */
+ret_code_t nrf_twi_sensor_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t const * p_data,
+ uint8_t length,
+ bool copy_flag);
+
+/**
+ * @brief Function for writing to sensor register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] sensor_addr Sensor address.
+ * @param[in] reg_address Register address.
+ * @param[in] p_data Pointer to data to be written.
+ * @param[in] length Number of bytes to write.
+ *
+ * @note Data is copied into internal buffer.
+ * Length has to be less than NRF_TWI_SENSOR_SEND_BUF_SIZE.
+ *
+ * @retval NRF_ERROR_NO_MEM If there is no memory in sensor buffer
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to copy more bytes than
+ * NRF_TWI_SENSOR_SEND_BUF_SIZE - 1.
+ * One byte reserved for register address.
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval other Error code from TWI manager @ref nrf_twi_mngr_schedule.
+ */
+ret_code_t nrf_twi_sensor_reg_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ uint8_t * p_data,
+ uint8_t length);
+
+/**
+ * @brief Function for getting maximum utilization of sensor buffer.
+ *
+ * @param[in] p_twi_sensor Pointer to sensor buffer.
+ *
+ * @return Maximum utilization.
+ */
+__STATIC_INLINE uint8_t nrf_twi_sensor_max_util_get(nrf_twi_sensor_t const * p_twi_sensor);
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_twi_sensor_max_util_get(nrf_twi_sensor_t const * p_twi_sensor)
+{
+ return nrf_balloc_max_utilization_get(p_twi_sensor->p_pool);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SENSOR_COMMON_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c
new file mode 100644
index 0000000..a5dd337
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_UART)
+#include "app_uart.h"
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+
+static uint8_t tx_buffer[1];
+static uint8_t rx_buffer[1];
+static volatile bool rx_done;
+static app_uart_event_handler_t m_event_handler; /**< Event handler function. */
+static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
+{
+ if (p_event->type == NRF_DRV_UART_EVT_RX_DONE)
+ {
+ app_uart_evt_t app_uart_event;
+ app_uart_event.evt_type = APP_UART_DATA;
+ app_uart_event.data.value = p_event->data.rxtx.p_data[0];
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ rx_done = true;
+ m_event_handler(&app_uart_event);
+ }
+ else if (p_event->type == NRF_DRV_UART_EVT_ERROR)
+ {
+ app_uart_evt_t app_uart_event;
+ app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
+ app_uart_event.data.error_communication = p_event->data.error.error_mask;
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ m_event_handler(&app_uart_event);
+ }
+ else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
+ {
+ // Last byte from FIFO transmitted, notify the application.
+ // Notify that new data is available if this was first byte put in the buffer.
+ app_uart_evt_t app_uart_event;
+ app_uart_event.evt_type = APP_UART_TX_EMPTY;
+ m_event_handler(&app_uart_event);
+ }
+}
+
+uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
+ app_uart_buffers_t * p_buffers,
+ app_uart_event_handler_t event_handler,
+ app_irq_priority_t irq_priority)
+{
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate;
+ config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ?
+ NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED;
+ config.interrupt_priority = irq_priority;
+ config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED;
+ config.pselcts = p_comm_params->cts_pin_no;
+ config.pselrts = p_comm_params->rts_pin_no;
+ config.pselrxd = p_comm_params->rx_pin_no;
+ config.pseltxd = p_comm_params->tx_pin_no;
+
+ m_event_handler = event_handler;
+
+ rx_done = false;
+
+ uint32_t err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler);
+ VERIFY_SUCCESS(err_code);
+
+ // Turn on receiver if RX pin is connected
+ if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED)
+ {
+ return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1);
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+uint32_t app_uart_get(uint8_t * p_byte)
+{
+ ASSERT(p_byte);
+ uint32_t err_code = NRF_SUCCESS;
+ if (rx_done)
+ {
+ *p_byte = rx_buffer[0];
+ rx_done = false;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+ return err_code;
+}
+
+uint32_t app_uart_put(uint8_t byte)
+{
+ tx_buffer[0] = byte;
+ ret_code_t ret = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
+ if (NRF_ERROR_BUSY == ret)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ else if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+uint32_t app_uart_flush(void)
+{
+ return NRF_SUCCESS;
+}
+
+uint32_t app_uart_close(void)
+{
+ nrf_drv_uart_uninit(&app_uart_inst);
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h
new file mode 100644
index 0000000..1858267
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup app_uart UART module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief UART module interface.
+ */
+
+#ifndef APP_UART_H__
+#define APP_UART_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */
+
+/**@brief UART Flow Control modes for the peripheral.
+ */
+typedef enum
+{
+ APP_UART_FLOW_CONTROL_DISABLED, /**< UART Hw Flow Control is disabled. */
+ APP_UART_FLOW_CONTROL_ENABLED, /**< Standard UART Hw Flow Control is enabled. */
+} app_uart_flow_control_t;
+
+/**@brief UART communication structure holding configuration settings for the peripheral.
+ */
+typedef struct
+{
+ uint32_t rx_pin_no; /**< RX pin number. */
+ uint32_t tx_pin_no; /**< TX pin number. */
+ uint32_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */
+ uint32_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */
+ app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */
+ bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */
+ uint32_t baud_rate; /**< Baud rate configuration. */
+} app_uart_comm_params_t;
+
+/**@brief UART buffer for transmitting/receiving data.
+ */
+typedef struct
+{
+ uint8_t * rx_buf; /**< Pointer to the RX buffer. */
+ uint32_t rx_buf_size; /**< Size of the RX buffer. */
+ uint8_t * tx_buf; /**< Pointer to the TX buffer. */
+ uint32_t tx_buf_size; /**< Size of the TX buffer. */
+} app_uart_buffers_t;
+
+/**@brief Enumeration which defines events used by the UART module upon data reception or error.
+ *
+ * @details The event type is used to indicate the type of additional information in the event
+ * @ref app_uart_evt_t.
+ */
+typedef enum
+{
+ APP_UART_DATA_READY, /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */
+ APP_UART_FIFO_ERROR, /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */
+ APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */
+ APP_UART_TX_EMPTY, /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */
+ APP_UART_DATA, /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */
+} app_uart_evt_type_t;
+
+/**@brief Struct containing events from the UART module.
+ *
+ * @details The app_uart_evt_t is used to notify the application of asynchronous events when data
+ * are received on the UART peripheral or in case an error occured during data reception.
+ */
+typedef struct
+{
+ app_uart_evt_type_t evt_type; /**< Type of event. */
+ union
+ {
+ uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */
+ uint32_t error_code; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
+ uint8_t value; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
+ } data;
+} app_uart_evt_t;
+
+/**@brief Function for handling app_uart event callback.
+ *
+ * @details Upon an event in the app_uart module this callback function will be called to notify
+ * the application about the event.
+ *
+ * @param[in] p_app_uart_event Pointer to UART event.
+ */
+typedef void (* app_uart_event_handler_t) (app_uart_evt_t * p_app_uart_event);
+
+/**@brief Macro for safe initialization of the UART module in a single user instance when using
+ * a FIFO together with UART.
+ *
+ * @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
+ * @param[in] RX_BUF_SIZE Size of desired RX buffer, must be a power of 2 or ZERO (No FIFO).
+ * @param[in] TX_BUF_SIZE Size of desired TX buffer, must be a power of 2 or ZERO (No FIFO).
+ * @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
+ * UART module.
+ * @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
+ * @param[out] ERR_CODE The return value of the UART initialization function will be
+ * written to this parameter.
+ *
+ * @note Since this macro allocates a buffer and registers the module as a GPIOTE user when flow
+ * control is enabled, it must only be called once.
+ */
+#define APP_UART_FIFO_INIT(P_COMM_PARAMS, RX_BUF_SIZE, TX_BUF_SIZE, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
+ do \
+ { \
+ app_uart_buffers_t buffers; \
+ static uint8_t rx_buf[RX_BUF_SIZE]; \
+ static uint8_t tx_buf[TX_BUF_SIZE]; \
+ \
+ buffers.rx_buf = rx_buf; \
+ buffers.rx_buf_size = sizeof (rx_buf); \
+ buffers.tx_buf = tx_buf; \
+ buffers.tx_buf_size = sizeof (tx_buf); \
+ ERR_CODE = app_uart_init(P_COMM_PARAMS, &buffers, EVT_HANDLER, IRQ_PRIO); \
+ } while (0)
+
+/**@brief Macro for safe initialization of the UART module in a single user instance.
+ *
+ * @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
+ * @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
+ * UART module.
+ * @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
+ * @param[out] ERR_CODE The return value of the UART initialization function will be
+ * written to this parameter.
+ *
+ * @note Since this macro allocates registers the module as a GPIOTE user when flow control is
+ * enabled, it must only be called once.
+ */
+#define APP_UART_INIT(P_COMM_PARAMS, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
+ do \
+ { \
+ ERR_CODE = app_uart_init(P_COMM_PARAMS, NULL, EVT_HANDLER, IRQ_PRIO); \
+ } while (0)
+
+/**@brief Function for initializing the UART module. Use this initialization when several instances of the UART
+ * module are needed.
+ *
+ *
+ * @note Normally single initialization should be done using the APP_UART_INIT() or
+ * APP_UART_INIT_FIFO() macro depending on whether the FIFO should be used by the UART, as
+ * that will allocate the buffers needed by the UART module (including aligning the buffer
+ * correctly).
+
+ * @param[in] p_comm_params Pin and communication parameters.
+ * @param[in] p_buffers RX and TX buffers, NULL is FIFO is not used.
+ * @param[in] error_handler Function to be called in case of an error.
+ * @param[in] irq_priority Interrupt priority level.
+ *
+ * @retval NRF_SUCCESS If successful initialization.
+ * @retval NRF_ERROR_INVALID_LENGTH If a provided buffer is not a power of two.
+ * @retval NRF_ERROR_NULL If one of the provided buffers is a NULL pointer.
+ *
+ * The below errors are propagated by the UART module to the caller upon registration when Hardware
+ * Flow Control is enabled. When Hardware Flow Control is not used, these errors cannot occur.
+ * @retval NRF_ERROR_INVALID_STATE The GPIOTE module is not in a valid state when registering
+ * the UART module as a user.
+ * @retval NRF_ERROR_INVALID_PARAM The UART module provides an invalid callback function when
+ * registering the UART module as a user.
+ * Or the value pointed to by *p_uart_uid is not a valid
+ * GPIOTE number.
+ * @retval NRF_ERROR_NO_MEM GPIOTE module has reached the maximum number of users.
+ */
+uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
+ app_uart_buffers_t * p_buffers,
+ app_uart_event_handler_t error_handler,
+ app_irq_priority_t irq_priority);
+
+/**@brief Function for getting a byte from the UART.
+ *
+ * @details This function will get the next byte from the RX buffer. If the RX buffer is empty
+ * an error code will be returned and the app_uart module will generate an event upon
+ * reception of the first byte which is added to the RX buffer.
+ *
+ * @param[out] p_byte Pointer to an address where next byte received on the UART will be copied.
+ *
+ * @retval NRF_SUCCESS If a byte has been received and pushed to the pointer provided.
+ * @retval NRF_ERROR_NOT_FOUND If no byte is available in the RX buffer of the app_uart module.
+ */
+uint32_t app_uart_get(uint8_t * p_byte);
+
+/**@brief Function for putting a byte on the UART.
+ *
+ * @details This call is non-blocking.
+ *
+ * @param[in] byte Byte to be transmitted on the UART.
+ *
+ * @retval NRF_SUCCESS If the byte was successfully put on the TX buffer for transmission.
+ * @retval NRF_ERROR_NO_MEM If no more space is available in the TX buffer.
+ * NRF_ERROR_NO_MEM may occur if flow control is enabled and CTS signal
+ * is high for a long period and the buffer fills up.
+ * @retval NRF_ERROR_INTERNAL If UART driver reported error.
+ */
+uint32_t app_uart_put(uint8_t byte);
+
+/**@brief Function for flushing the RX and TX buffers (Only valid if FIFO is used).
+ * This function does nothing if FIFO is not used.
+ *
+ * @retval NRF_SUCCESS Flushing completed (Current implementation will always succeed).
+ */
+uint32_t app_uart_flush(void);
+
+/**@brief Function for closing the UART module.
+ *
+ * @retval NRF_SUCCESS If successfully closed.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid user id is provided or the user id differs from
+ * the current active user.
+ */
+uint32_t app_uart_close(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //APP_UART_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c
new file mode 100644
index 0000000..7ff7bd8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_UART)
+#include "app_uart.h"
+#include "app_fifo.h"
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+
+static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);
+
+static __INLINE uint32_t fifo_length(app_fifo_t * const fifo)
+{
+ uint32_t tmp = fifo->read_pos;
+ return fifo->write_pos - tmp;
+}
+
+#define FIFO_LENGTH(F) fifo_length(&F) /**< Macro to calculate length of a FIFO. */
+
+
+static app_uart_event_handler_t m_event_handler; /**< Event handler function. */
+static uint8_t tx_buffer[1];
+static uint8_t rx_buffer[1];
+static bool m_rx_ovf;
+
+static app_fifo_t m_rx_fifo; /**< RX FIFO buffer for storing data received on the UART until the application fetches them using app_uart_get(). */
+static app_fifo_t m_tx_fifo; /**< TX FIFO buffer for storing data to be transmitted on the UART when TXD is ready. Data is put to the buffer on using app_uart_put(). */
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
+{
+ app_uart_evt_t app_uart_event;
+ uint32_t err_code;
+
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ // Write received byte to FIFO.
+ err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]);
+ if (err_code != NRF_SUCCESS)
+ {
+ app_uart_event.evt_type = APP_UART_FIFO_ERROR;
+ app_uart_event.data.error_code = err_code;
+ m_event_handler(&app_uart_event);
+ }
+ // Notify that there are data available.
+ else if (FIFO_LENGTH(m_rx_fifo) != 0)
+ {
+ app_uart_event.evt_type = APP_UART_DATA_READY;
+ m_event_handler(&app_uart_event);
+ }
+
+ // Start new RX if size in buffer.
+ if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask)
+ {
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ }
+ else
+ {
+ // Overflow in RX FIFO.
+ m_rx_ovf = true;
+ }
+
+ break;
+
+ case NRF_DRV_UART_EVT_ERROR:
+ app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
+ app_uart_event.data.error_communication = p_event->data.error.error_mask;
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ m_event_handler(&app_uart_event);
+ break;
+
+ case NRF_DRV_UART_EVT_TX_DONE:
+ // Get next byte from FIFO.
+ if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
+ {
+ (void)nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
+ }
+ else
+ {
+ // Last byte from FIFO transmitted, notify the application.
+ app_uart_event.evt_type = APP_UART_TX_EMPTY;
+ m_event_handler(&app_uart_event);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
+ app_uart_buffers_t * p_buffers,
+ app_uart_event_handler_t event_handler,
+ app_irq_priority_t irq_priority)
+{
+ uint32_t err_code;
+
+ m_event_handler = event_handler;
+
+ if (p_buffers == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Configure buffer RX buffer.
+ err_code = app_fifo_init(&m_rx_fifo, p_buffers->rx_buf, p_buffers->rx_buf_size);
+ VERIFY_SUCCESS(err_code);
+
+ // Configure buffer TX buffer.
+ err_code = app_fifo_init(&m_tx_fifo, p_buffers->tx_buf, p_buffers->tx_buf_size);
+ VERIFY_SUCCESS(err_code);
+
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate;
+ config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ?
+ NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED;
+ config.interrupt_priority = irq_priority;
+ config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED;
+ config.pselcts = p_comm_params->cts_pin_no;
+ config.pselrts = p_comm_params->rts_pin_no;
+ config.pselrxd = p_comm_params->rx_pin_no;
+ config.pseltxd = p_comm_params->tx_pin_no;
+
+ err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler);
+ VERIFY_SUCCESS(err_code);
+ m_rx_ovf = false;
+
+ // Turn on receiver if RX pin is connected
+ if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED)
+ {
+ return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1);
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+uint32_t app_uart_flush(void)
+{
+ uint32_t err_code;
+
+ err_code = app_fifo_flush(&m_rx_fifo);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = app_fifo_flush(&m_tx_fifo);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_uart_get(uint8_t * p_byte)
+{
+ ASSERT(p_byte);
+ bool rx_ovf = m_rx_ovf;
+
+ ret_code_t err_code = app_fifo_get(&m_rx_fifo, p_byte);
+
+ // If FIFO was full new request to receive one byte was not scheduled. Must be done here.
+ if (rx_ovf)
+ {
+ m_rx_ovf = false;
+ uint32_t uart_err_code = nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+
+ // RX resume should never fail.
+ APP_ERROR_CHECK(uart_err_code);
+ }
+
+ return err_code;
+}
+
+
+uint32_t app_uart_put(uint8_t byte)
+{
+ uint32_t err_code;
+ err_code = app_fifo_put(&m_tx_fifo, byte);
+ if (err_code == NRF_SUCCESS)
+ {
+ // The new byte has been added to FIFO. It will be picked up from there
+ // (in 'uart_event_handler') when all preceding bytes are transmitted.
+ // But if UART is not transmitting anything at the moment, we must start
+ // a new transmission here.
+ if (!nrf_drv_uart_tx_in_progress(&app_uart_inst))
+ {
+ // This operation should be almost always successful, since we've
+ // just added a byte to FIFO, but if some bigger delay occurred
+ // (some heavy interrupt handler routine has been executed) since
+ // that time, FIFO might be empty already.
+ if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
+ {
+ err_code = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
+ }
+ }
+ }
+ return err_code;
+}
+
+
+uint32_t app_uart_close(void)
+{
+ nrf_drv_uart_uninit(&app_uart_inst);
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c
new file mode 100644
index 0000000..8e85bca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+/** @file
+ *
+ * @defgroup retarget Retarget layer for stdio functions
+ * @{
+ * @ingroup app_common
+ * @} */
+#if NRF_MODULE_ENABLED(RETARGET)
+#if !defined(NRF_LOG_USES_RTT) || NRF_LOG_USES_RTT != 1
+#if !defined(HAS_SIMPLE_UART_RETARGET)
+
+
+#include <stdio.h>
+#include <stdint.h>
+#include "app_uart.h"
+#include "nrf_error.h"
+
+
+#if defined(__CC_ARM)
+
+// This part is taken from MDK-ARM template file and is required here to prevent
+// linker from selecting libraries functions that use semihosting and failing
+// because of multiple definitions of fgetc() and fputc().
+// Refer to: http://www.keil.com/support/man/docs/gsac/gsac_retargetcortex.htm
+// -- BEGIN --
+struct __FILE { int handle; /* Add whatever you need here */ };
+FILE __stdout;
+FILE __stdin;
+// --- END ---
+
+int fgetc(FILE * p_file)
+{
+ uint8_t input;
+ while (app_uart_get(&input) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+ return input;
+}
+
+int fputc(int ch, FILE * p_file)
+{
+ UNUSED_PARAMETER(p_file);
+
+ UNUSED_VARIABLE(app_uart_put((uint8_t)ch));
+ return ch;
+}
+
+#elif defined(__GNUC__) && defined(__SES_ARM)
+
+int __getchar(FILE * p_file)
+{
+ uint8_t input;
+ while (app_uart_get(&input) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+ return input;
+}
+
+int __putchar(int ch, FILE * p_file)
+{
+ UNUSED_PARAMETER(p_file);
+
+ UNUSED_VARIABLE(app_uart_put((uint8_t)ch));
+ return ch;
+}
+
+#elif defined(__GNUC__) && !defined(__SES_ARM)
+
+int _write(int file, const char * p_char, int len)
+{
+ int i;
+
+ UNUSED_PARAMETER(file);
+
+ for (i = 0; i < len; i++)
+ {
+ UNUSED_VARIABLE(app_uart_put(*p_char++));
+ }
+
+ return len;
+}
+
+int _read(int file, char * p_char, int len)
+{
+ UNUSED_PARAMETER(file);
+ while (app_uart_get((uint8_t *)p_char) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+
+ return 1;
+}
+#elif defined(__ICCARM__)
+
+size_t __write(int handle, const unsigned char * buffer, size_t size)
+{
+ int i;
+ UNUSED_PARAMETER(handle);
+ for (i = 0; i < size; i++)
+ {
+ UNUSED_VARIABLE(app_uart_put(*buffer++));
+ }
+ return size;
+}
+
+size_t __read(int handle, unsigned char * buffer, size_t size)
+{
+ UNUSED_PARAMETER(handle);
+ UNUSED_PARAMETER(size);
+ while (app_uart_get((uint8_t *)buffer) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+
+ return 1;
+}
+
+long __lseek(int handle, long offset, int whence)
+{
+ return -1;
+}
+int __close(int handle)
+{
+ return 0;
+}
+int remove(const char * filename)
+{
+ return 0;
+}
+
+#endif
+
+#endif // !defined(HAS_SIMPLE_UART_RETARGET)
+#endif // NRF_LOG_USES_RTT != 1
+#endif //NRF_MODULE_ENABLED(RETARGET)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c
new file mode 100644
index 0000000..e5cbcf8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c
@@ -0,0 +1,1766 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD)
+
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "nrf_power.h"
+#include "nrf_drv_clock.h"
+#include "nrf_drv_power.h"
+#if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#include "nrf_atfifo.h"
+#include "nrf_atomic.h"
+#endif
+
+#define NRF_LOG_MODULE_NAME app_usbd
+
+#if APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/* Base variables tests */
+
+/* Check event of app_usbd_event_type_t enumerator */
+STATIC_ASSERT((int32_t)APP_USBD_EVT_FIRST_POWER == (int32_t)NRF_DRV_USBD_EVT_CNT);
+STATIC_ASSERT(sizeof(app_usbd_event_type_t) == sizeof(nrf_drv_usbd_event_type_t));
+
+STATIC_ASSERT(sizeof(app_usbd_descriptor_header_t) == 2);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_device_t) == 18);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_configuration_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_iface_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_ep_t) == 7);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_iad_t) == 8);
+
+STATIC_ASSERT(sizeof(app_usbd_setup_t) == sizeof(nrf_drv_usbd_setup_t));
+
+/**
+ * @internal
+ * @defgroup app_usbd_internals USBD library internals
+ * @ingroup app_usbd
+ *
+ * Internal variables, auxiliary macros and functions of USBD library.
+ * @{
+ */
+
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief The last received frame number.
+ */
+static uint16_t m_last_frame;
+#endif
+
+/**
+ * @brief Variable type for endpoint configuration
+ *
+ * Each endpoint would have assigned this type of configuration structure.
+ */
+typedef struct
+{
+ /**
+ * @brief The class instance
+ *
+ * The pointer to the class instance that is connected to the endpoint.
+ */
+ app_usbd_class_inst_t const * p_cinst;
+
+ /**
+ * @brief Endpoint event handler.
+ *
+ * Event handler for the endpoint.
+ * It is set to event handler for the class instance during connection by default,
+ * but it can be then updated for as a reaction for @ref APP_USBD_EVT_ATTACHED event.
+ * This way we can speed up the interpretation of endpoint related events.
+ */
+ app_usbd_ep_event_handler_t event_handler;
+}app_usbd_ep_conf_t;
+
+
+/**
+ * @brief Internal event with SOF counter.
+ */
+typedef struct
+{
+ app_usbd_internal_evt_t evt; //!< Internal event type
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE) \
+ || defined(__SDK_DOXYGEN__)
+ uint16_t sof_cnt; //!< Number of the SOF events that appears before current event
+ uint16_t start_frame; //!< Number of the SOF frame that starts this event
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+} app_usbd_internal_queue_evt_t;
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Event queue
+ *
+ * The queue with events to be processed
+ */
+NRF_ATFIFO_DEF(m_event_queue, app_usbd_internal_queue_evt_t, APP_USBD_CONFIG_EVENT_QUEUE_SIZE);
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE) \
+ || defined(__SDK_DOXYGEN__)
+
+/** @brief SOF events counter */
+static nrf_atomic_u32_t m_sof_events_cnt;
+
+/** @brief SOF Frame counter */
+static uint16_t m_event_frame;
+
+// Limit of SOF events stacked until warning message.
+#define APP_USBD_SOF_WARNING_LIMIT 500
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ // || defined(__SDK_DOXYGEN__)
+
+#endif
+
+/**
+ * @brief Instances connected with IN endpoints
+ *
+ * Array of instance pointers connected with every IN endpoint.
+ * @sa m_epout_instances
+ */
+static app_usbd_ep_conf_t m_epin_conf[NRF_USBD_EPIN_CNT];
+
+/**
+ * @brief Instances connected with OUT endpoints
+ *
+ * Array of instance pointers connected with every OUT endpoint.
+ * @sa m_epin_instances
+ */
+static app_usbd_ep_conf_t m_epout_conf[NRF_USBD_EPIN_CNT];
+
+/**
+ * @brief Beginning of classes list
+ *
+ * All enabled in current configuration instances are connected into
+ * a single linked list chain.
+ * This variable points to first element.
+ * Core class instance (connected to endpoint 0) is not listed here.
+ */
+static app_usbd_class_inst_t const * m_p_first_cinst;
+
+/**
+ * @brief Classes list that requires SOF events
+ *
+ * @todo RK Implement and documentation
+ */
+static app_usbd_class_inst_t const * m_p_first_sof_cinst;
+
+/**
+ * @brief Default configuration (when NULL is passed to @ref app_usbd_init).
+ */
+static const app_usbd_config_t m_default_conf = {
+#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
+ .ev_handler = app_usbd_event_execute,
+#endif
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+ .ev_isr_handler = NULL,
+#endif
+ .ev_state_proc = NULL,
+ .enable_sof = false
+};
+
+/**
+ * @brief SUSPEND state machine states
+ *
+ * The enumeration of internal SUSPEND state machine states.
+ */
+typedef enum
+{
+ SUSTATE_STOPPED, /**< The USB driver was not started */
+ SUSTATE_STARTED, /**< The USB driver was started - waiting for USB RESET */
+ SUSTATE_ACTIVE, /**< Active state */
+ SUSTATE_SUSPENDING, /**< Suspending - waiting for the user to acknowledge */
+ SUSTATE_SUSPEND, /**< Suspended */
+ SUSTATE_RESUMING, /**< Resuming - waiting for clock */
+ SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ, /**< Waking up - waiting for clock and WUREQ from driver */
+ SUSTATE_WAKINGUP_WAITING_HFCLK, /**< Waking up - waiting for HFCLK (WUREQ detected) */
+ SUSTATE_WAKINGUP_WAITING_WREQ, /**< Waking up - waiting for WREQ (HFCLK active) */
+}app_usbd_sustate_t;
+
+/**
+ * @brief Current suspend state
+ *
+ * The state of the suspend state machine
+ */
+static app_usbd_sustate_t m_sustate;
+
+/**
+ * @brief Remote wake-up register/unregister
+ *
+ * Counter incremented when appended instance required remote wake-up functionality.
+ * It should be decremented when the class is removed.
+ * When this counter is not zero, remote wake-up functionality is activated inside core.
+ */
+static uint8_t m_rwu_registered_counter;
+
+/**
+ * @brief Current configuration.
+ */
+static app_usbd_config_t m_current_conf;
+
+/**
+ * @brief Class interface call: event handler
+ *
+ * @ref app_usbd_class_interface_t::event_handler
+ *
+ * @param[in] p_cinst Class instance
+ * @param[in] p_event Event passed to class instance
+ *
+ * @return Standard error code @ref ret_code_t
+ * @retval NRF_SUCCESS event handled successfully
+ * @retval NRF_ERROR_NOT_SUPPORTED unsupported event
+ * */
+static inline ret_code_t class_event_handler(app_usbd_class_inst_t const * const p_cinst,
+ app_usbd_complex_evt_t const * const p_event)
+{
+ ASSERT(p_cinst != NULL);
+ ASSERT(p_cinst->p_class_methods != NULL);
+ ASSERT(p_cinst->p_class_methods->event_handler != NULL);
+ return p_cinst->p_class_methods->event_handler(p_cinst, p_event);
+}
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief User event handler call (passed via configuration).
+ *
+ * @param p_event Handler of an event that is going to be added into queue.
+ * @param queued The event is visible in the queue.
+ */
+static inline void user_event_handler(app_usbd_internal_evt_t const * const p_event, bool queued)
+{
+ if ((m_current_conf.ev_isr_handler) != NULL)
+ {
+ m_current_conf.ev_isr_handler(p_event, queued);
+ }
+}
+#endif
+
+/**
+ * @brief User event processor call (passed via configuration)
+ *
+ * @param event Event type.
+ */
+static inline void user_event_state_proc(app_usbd_event_type_t event)
+{
+ if ((m_current_conf.ev_state_proc) != NULL)
+ {
+ m_current_conf.ev_state_proc(event);
+ }
+}
+
+/**
+ * @brief Find a specified descriptor
+ *
+ * @param[in] p_cinst Class instance
+ * @param[in] desc_type Descriptor type @ref app_usbd_descriptor_t
+ * @param[in] desc_index Descriptor index
+ * @param[out] p_desc Pointer to escriptor
+ * @param[out] p_desc_len Length of descriptor
+ *
+ * @return Standard error code @ref ret_code_t
+ * @retval NRF_SUCCESS descriptor successfully found
+ * @retval NRF_ERROR_NOT_FOUND descriptor not found
+ * */
+ret_code_t app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t desc_type,
+ uint8_t desc_index,
+ uint8_t * p_desc,
+ size_t * p_desc_len)
+{
+ app_usbd_class_descriptor_ctx_t siz;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&siz);
+ uint32_t total_size = 0;
+ while(p_cinst->p_class_methods->feed_descriptors(&siz, p_cinst, NULL, sizeof(uint8_t)))
+ {
+ total_size++;
+ }
+
+ uint8_t cur_len = 0;
+ uint32_t cur_size = 0;
+
+ uint8_t index = 0;
+ app_usbd_class_descriptor_ctx_t descr;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&descr);
+
+ while(cur_size < total_size)
+ {
+ /* First byte of a descriptor is its size */
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ &cur_len,
+ sizeof(uint8_t)));
+
+ /* Second byte is type of the descriptor */
+ uint8_t type;
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ &type,
+ sizeof(uint8_t)));
+
+ if(type == desc_type)
+ {
+ if(index == desc_index)
+ {
+ /* Copy the length of descriptor to *p_desc_len */
+ *p_desc_len = cur_len;
+ /* Two first bytes of descriptor have already been fed - copy them to *p_desc */
+ *p_desc++ = cur_len;
+ *p_desc++ = desc_type;
+ /* Copy the rest of descriptor to *p_desc */
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ p_desc,
+ cur_len-2));
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ index++;
+ }
+ }
+ /* Fast-forward through unmatched descriptor */
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ NULL,
+ cur_len-2));
+ cur_size += cur_len;
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+/**
+ * @brief Access into selected endpoint configuration structure
+ *
+ * @param ep Endpoint address
+ * @return A pointer to the endpoint configuration structure
+ *
+ * @note This function would assert when endpoint number is not correct and debugging is enabled.
+ */
+static app_usbd_ep_conf_t * app_usbd_ep_conf_access(nrf_drv_usbd_ep_t ep)
+{
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ uint8_t nr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(nr < NRF_USBD_EPIN_CNT);
+ return &m_epin_conf[nr];
+ }
+ else
+ {
+ uint8_t nr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(nr < NRF_USBD_EPOUT_CNT);
+ return &m_epout_conf[nr];
+ }
+}
+
+/**
+ * @brief Accessing instance connected with selected endpoint
+ *
+ * @param ep Endpoint number
+ *
+ * @return The pointer to the instance connected with endpoint
+ */
+static inline app_usbd_class_inst_t const * app_usbd_ep_instance_get(nrf_drv_usbd_ep_t ep)
+{
+ return app_usbd_ep_conf_access(ep)->p_cinst;
+}
+
+/**
+ * @brief Connect instance with selected endpoint
+ *
+ * This function configures instance connected to endpoint but also sets
+ * default event handler function pointer.
+ *
+ * @param ep Endpoint number
+ * @param p_cinst The instance to connect into the selected endpoint.
+ * NULL if endpoint is going to be disconnected.
+ *
+ * @note Disconnecting EP0 is not allowed and protected by assertion.
+ */
+static void app_usbd_ep_instance_set(nrf_drv_usbd_ep_t ep, app_usbd_class_inst_t const * p_cinst)
+{
+ app_usbd_ep_conf_t * p_ep_conf = app_usbd_ep_conf_access(ep);
+ /* Set instance and default event handler */
+ p_ep_conf->p_cinst = p_cinst;
+ if (p_cinst == NULL)
+ {
+ ASSERT((ep != NRF_DRV_USBD_EPOUT0) && (ep != NRF_DRV_USBD_EPIN0)); /* EP0 should never be disconnected */
+ p_ep_conf->event_handler = NULL;
+ }
+ else
+ {
+ p_ep_conf->event_handler = p_cinst->p_class_methods->event_handler;
+ }
+}
+
+/**
+ * @brief Call the core handler
+ *
+ * Core instance is special kind of instance that is connected only to endpoint 0.
+ * It is not present in instance list.
+ * This auxiliary function makes future changes easier.
+ * Just call the event instance for core module here.
+ */
+static inline ret_code_t app_usbd_core_handler_call(app_usbd_internal_evt_t const * const p_event)
+{
+ return m_epout_conf[0].event_handler(
+ m_epout_conf[0].p_cinst,
+ (app_usbd_complex_evt_t const *)p_event);
+}
+
+
+
+/**
+ * @brief Add event for execution
+ *
+ * Dependent on configuration event would be executed in place or would be added into queue
+ * to be executed later.
+ *
+ * @param p_event Event to be executed
+ */
+static inline void app_usbd_event_add(app_usbd_internal_evt_t const * const p_event)
+{
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ if (p_event->app_evt.type == APP_USBD_EVT_DRV_SOF)
+ {
+ CRITICAL_REGION_ENTER();
+ if (m_sof_events_cnt == 0)
+ {
+ m_event_frame = p_event->drv_evt.data.sof.framecnt;
+ }
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_sof_events_cnt, 1));
+ CRITICAL_REGION_EXIT();
+
+ user_event_handler(p_event, true);
+ if (m_sof_events_cnt == APP_USBD_SOF_WARNING_LIMIT)
+ {
+ NRF_LOG_WARNING("Stacked over %d SOF events.", APP_USBD_SOF_WARNING_LIMIT);
+ }
+ return;
+ }
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+ if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_INTERRUPT)
+ {
+ if (p_event->app_evt.type == APP_USBD_EVT_DRV_SOF)
+ {
+ user_event_handler(p_event, false);
+ app_usbd_event_execute(p_event);
+ return;
+ }
+ }
+
+ nrf_atfifo_item_put_t cx;
+ app_usbd_internal_queue_evt_t * p_event_item = nrf_atfifo_item_alloc(m_event_queue, &cx);
+
+ if (NULL != p_event_item)
+ {
+ bool visible;
+ p_event_item->evt = *p_event;
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ CRITICAL_REGION_ENTER();
+ p_event_item->start_frame = m_event_frame - m_sof_events_cnt + 1;
+ p_event_item->sof_cnt = nrf_atomic_u32_fetch_store(&m_sof_events_cnt, 0);
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+ visible = nrf_atfifo_item_put(m_event_queue, &cx);
+ user_event_handler(p_event, visible);
+ }
+ else
+ {
+ NRF_LOG_ERROR("Event queue full.");
+ }
+#else
+ m_current_conf.ev_handler(p_event);
+#endif
+}
+
+/**
+ * @brief Power event handler
+ *
+ * The function that pushes power events into the queue
+ * @param p_event
+ */
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+static void app_usbd_power_event_handler(nrf_drv_power_usb_evt_t event)
+{
+ switch(event)
+ {
+ case NRF_DRV_POWER_USB_EVT_DETECTED:
+ {
+ static const app_usbd_internal_evt_t ev = {
+ .type = APP_USBD_EVT_POWER_DETECTED
+ };
+ app_usbd_event_add(&ev);
+ break;
+ }
+ case NRF_DRV_POWER_USB_EVT_REMOVED:
+ {
+ static const app_usbd_internal_evt_t ev = {
+ .type = APP_USBD_EVT_POWER_REMOVED
+ };
+ app_usbd_event_add(&ev);
+ break;
+ }
+ case NRF_DRV_POWER_USB_EVT_READY:
+ {
+ static const app_usbd_internal_evt_t ev = {
+ .type = APP_USBD_EVT_POWER_READY
+ };
+ app_usbd_event_add(&ev);
+ break;
+ }
+ default:
+ ASSERT(false);
+ }
+}
+#endif
+
+/**
+ * @brief Event handler
+ *
+ * The function that pushes the event into the queue
+ * @param p_event
+ */
+static void app_usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event)
+{
+ app_usbd_event_add((app_usbd_internal_evt_t const *)p_event);
+}
+
+/**
+ * @brief HF clock ready event handler
+ *
+ * Function that is called when high frequency clock is started
+ *
+ * @param event Event type that comes from clock driver
+ */
+static void app_usbd_hfclk_ready(nrf_drv_clock_evt_type_t event)
+{
+ ASSERT(NRF_DRV_CLOCK_EVT_HFCLK_STARTED == event);
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_HFCLK_READY
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+/**
+ * @brief Check if the HFCLK was requested in selected suspend state machine state
+ *
+ *
+ * @param sustate State to be checked
+ *
+ * @retval true High frequency clock was requested in selected state
+ * @retval false High frequency clock was released in selected state
+ */
+static inline bool app_usbd_sustate_with_requested_hfclk(app_usbd_sustate_t sustate)
+{
+ switch(sustate)
+ {
+ case SUSTATE_STOPPED: return false;
+ case SUSTATE_STARTED: return false;
+ case SUSTATE_ACTIVE: return true;
+ case SUSTATE_SUSPENDING: return false;
+ case SUSTATE_SUSPEND: return false;
+ case SUSTATE_RESUMING: return true;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ: return true;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK: return true;
+ case SUSTATE_WAKINGUP_WAITING_WREQ: return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Check it the HFCLK is running in selected suspend state machine state
+ *
+ * @param sustate State to be checked
+ *
+ * @retval true High frequency clock is running in selected state
+ * @retval false High frequency clock is released in selected state
+ */
+static inline bool app_usbd_sustate_with_running_hfclk(app_usbd_sustate_t sustate)
+{
+ switch(sustate)
+ {
+ case SUSTATE_STOPPED: return false;
+ case SUSTATE_STARTED: return false;
+ case SUSTATE_ACTIVE: return true;
+ case SUSTATE_SUSPENDING: return false;
+ case SUSTATE_SUSPEND: return false;
+ case SUSTATE_RESUMING: return false;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ: return false;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK: return false;
+ case SUSTATE_WAKINGUP_WAITING_WREQ: return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Get current suspend state machine state
+ *
+ * @return The state of the suspend state machine
+ */
+static inline app_usbd_sustate_t sustate_get(void)
+{
+ return m_sustate;
+}
+
+/**
+ * @brief Set current suspend state machine state
+ *
+ * @param sustate The requested state of the state machine
+ */
+static inline void sustate_set(app_usbd_sustate_t sustate)
+{
+ if (app_usbd_sustate_with_requested_hfclk(sustate) != app_usbd_sustate_with_requested_hfclk(m_sustate))
+ {
+ if (app_usbd_sustate_with_requested_hfclk(sustate))
+ {
+ static nrf_drv_clock_handler_item_t clock_handler_item =
+ {
+ .event_handler = app_usbd_hfclk_ready
+ };
+ nrf_drv_clock_hfclk_request(&clock_handler_item);
+ }
+ else
+ {
+ nrf_drv_clock_hfclk_release();
+ }
+ }
+ if (app_usbd_sustate_with_running_hfclk(sustate) != app_usbd_sustate_with_running_hfclk(m_sustate))
+ {
+ if (app_usbd_sustate_with_running_hfclk(sustate))
+ {
+ nrf_drv_usbd_active_irq_config();
+ }
+ else
+ {
+ nrf_drv_usbd_suspend_irq_config();
+ }
+ }
+ m_sustate = sustate;
+}
+
+/**
+ * @brief Default selection function for interface
+ *
+ * This function just enables and clears interface endpoints
+ *
+ * @param p_inst See the documentation for @ref app_usbd_iface_select
+ * @param iface_idx See the documentation for @ref app_usbd_iface_select
+ * @param alternate See the documentation for @ref app_usbd_iface_select
+ * @return
+ */
+static inline ret_code_t default_iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate)
+{
+ ASSERT(iface_idx <= app_usbd_class_iface_count_get(p_inst));
+
+ if (alternate != 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ for (uint8_t i = 0; i < ep_count; ++i)
+ {
+ /* Enable every endpoint */
+ app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, i);
+ app_usbd_ep_enable(p_ep->address);
+ }
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Default deselection function for interface
+ *
+ * This function just disables all interface endpoints.
+ *
+ * @param p_inst See the documentation for @ref app_usbd_iface_deselect
+ * @param iface_idx See the documentation for @ref app_usbd_iface_deselect
+ */
+static inline void default_iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ ASSERT(iface_idx <= app_usbd_class_iface_count_get(p_inst));
+
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ for (uint8_t i = 0; i < ep_count; ++i)
+ {
+ /* Disable every endpoint */
+ app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, i);
+ app_usbd_ep_disable(p_ep->address);
+ }
+}
+
+
+/** @} */
+
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+uint32_t app_usbd_sof_timestamp_get(void)
+{
+ return m_last_frame;
+}
+#endif
+
+ret_code_t app_usbd_init(app_usbd_config_t const * p_config)
+{
+ ASSERT(nrf_drv_clock_init_check());
+ ret_code_t ret;
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+ ret = NRF_ATFIFO_INIT(m_event_queue);
+ if (NRF_SUCCESS != ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+#endif
+
+ /* This is called at the beginning to secure multiple calls to init function */
+ ret = nrf_drv_usbd_init(app_usbd_event_handler);
+ if (NRF_SUCCESS != ret)
+ {
+ return ret;
+ }
+
+ /* Clear the variables */
+ m_sustate = SUSTATE_STOPPED;
+ m_p_first_cinst = NULL;
+ m_p_first_sof_cinst = NULL;
+ memset(m_epin_conf , 0, sizeof(m_epin_conf ));
+ memset(m_epout_conf, 0, sizeof(m_epout_conf));
+ /* Save the new configuration */
+ if (p_config == NULL)
+ {
+ m_current_conf = m_default_conf;
+ }
+ else
+ {
+ m_current_conf = *p_config;
+ }
+
+#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE))
+ if(m_current_conf.ev_handler == NULL)
+ {
+ m_current_conf.ev_handler = m_default_conf.ev_handler;
+ }
+#endif
+
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ ret = nrf_drv_power_init(NULL);
+ if ((ret != NRF_SUCCESS) && (ret != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ /* This should never happen */
+ APP_ERROR_HANDLER(ret);
+ }
+#endif
+
+ /*Pin core class to required endpoints*/
+ uint8_t iface_idx;
+ app_usbd_class_iface_conf_t const * p_iface;
+ app_usbd_class_inst_t const * const p_inst = app_usbd_core_instance_access();
+ iface_idx = 0;
+ while ((p_iface = app_usbd_class_iface_get(p_inst, iface_idx++)) != NULL)
+ {
+ uint8_t ep_idx = 0;
+ app_usbd_class_ep_conf_t const * p_ep;
+ while ((p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)) != NULL)
+ {
+ app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_inst);
+ }
+ }
+
+ /* Successfully attached */
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_INST_APPEND
+ };
+
+ ret = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)(&evt_data));
+ if (NRF_SUCCESS != ret)
+ {
+ UNUSED_RETURN_VALUE(nrf_drv_usbd_uninit());
+ return ret;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_uninit(void)
+{
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ nrf_drv_power_usbevt_uninit();
+#endif
+
+ /* We get this error at very beginning but it would be used at the end of the function */
+ const ret_code_t ret = nrf_drv_usbd_uninit();
+
+ /* Unchain instance list */
+ app_usbd_class_inst_t const * * pp_inst;
+ pp_inst = &m_p_first_cinst;
+ while (NULL != (*pp_inst))
+ {
+ app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_next;
+ (*pp_inst) = NULL;
+ pp_inst = pp_next;
+ }
+
+ /* Unchain SOF list */
+ pp_inst = &m_p_first_sof_cinst;
+ while (NULL != (*pp_inst))
+ {
+ app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_sof_next;
+ (*pp_inst) = NULL;
+ pp_inst = pp_next;
+ }
+
+ /* Clear all endpoints configurations */
+ memset(m_epin_conf , 0, sizeof(m_epin_conf ));
+ memset(m_epout_conf, 0, sizeof(m_epout_conf));
+ /* Clear current configuration */
+ memset(&m_current_conf, 0, sizeof(m_current_conf));
+
+ return ret;
+}
+
+
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ret_code_t app_usbd_power_events_enable(void)
+{
+ if (!nrf_drv_usbd_is_initialized() || nrf_drv_usbd_is_enabled())
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ASSERT((!APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || (USBD_CONFIG_IRQ_PRIORITY == POWER_CONFIG_IRQ_PRIORITY));
+
+ ret_code_t ret;
+ static const nrf_drv_power_usbevt_config_t config =
+ {
+ .handler = app_usbd_power_event_handler
+ };
+
+ ret = nrf_drv_power_usbevt_init(&config);
+ APP_ERROR_CHECK(ret);
+
+ return NRF_SUCCESS;
+}
+#endif /* APP_USBD_CONFIG_POWER_EVENTS_PROCESS */
+
+
+void app_usbd_enable(void)
+{
+ nrf_drv_usbd_enable();
+}
+
+
+void app_usbd_disable(void)
+{
+ ASSERT(!nrf_drv_usbd_is_started());
+ nrf_drv_usbd_disable();
+}
+
+
+void app_usbd_start(void)
+{
+ ASSERT(nrf_drv_usbd_is_enabled());
+
+ /* Check if interface numbers are in correct order */
+ if (APP_USBD_CONFIG_LOG_ENABLED)
+ {
+ uint8_t next_iface = 0;
+ for (app_usbd_class_inst_t const * * pp_inst = &m_p_first_cinst;
+ (*pp_inst) != NULL;
+ pp_inst = &(app_usbd_class_data_access(*pp_inst)->p_next))
+ {
+ uint8_t iface_idx = 0;
+ app_usbd_class_iface_conf_t const * p_iface;
+ while (NULL != (p_iface = app_usbd_class_iface_get(*pp_inst, iface_idx++)))
+ {
+ if (p_iface->number != next_iface)
+ {
+ NRF_LOG_WARNING("Unexpected interface number, expected %d, got %d",
+ next_iface,
+ p_iface->number);
+ }
+ ++next_iface;
+ }
+ }
+ }
+
+ /* Power should be already enabled - wait just in case if user calls
+ * app_usbd_start just after app_usbd_enable without waiting for the event. */
+ while (!nrf_power_usbregstatus_outrdy_get())
+ {
+ /* Wait for the power but terminate the function if USBD power disappears */
+ if (!nrf_power_usbregstatus_vbusdet_get())
+ return;
+ }
+
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_START_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+
+void app_usbd_stop(void)
+{
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STOP_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+void app_usbd_suspend_req(void)
+{
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_SUSPEND_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+bool app_usbd_wakeup_req(void)
+{
+ ASSERT(app_usbd_class_rwu_enabled_check());
+ if (!app_usbd_core_feature_state_get(APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP))
+ return false;
+
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_WAKEUP_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+ return true;
+}
+
+bool app_usbd_active_check(void)
+{
+ return (sustate_get() == SUSTATE_ACTIVE);
+}
+
+void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event)
+{
+ ASSERT(NULL != m_p_first_cinst);
+ /* If no event queue is implemented, it has to be ensured that this function is never called
+ * from the context higher than USB interrupt level
+ * If queue is implemented it would be called always from Thread level
+ * if the library is used correctly.
+ * NOTE: Higher interrupt level -> lower priority value.
+ */
+ ASSERT(USBD_CONFIG_IRQ_PRIORITY <= current_int_priority_get());
+
+ /* Note - there should never be situation that event is generated on disconnected endpoint */
+ switch (p_event->type)
+ {
+ case APP_USBD_EVT_START_REQ:
+ {
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STARTED
+ };
+
+ /* Send event to all classes */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const * )&evt_data));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data);
+ user_event_state_proc(APP_USBD_EVT_STARTED);
+
+ nrf_drv_usbd_start((NULL != m_p_first_sof_cinst) || (m_current_conf.enable_sof) || (APP_USBD_PROVIDE_SOF_TIMESTAMP));
+ app_usbd_all_iface_deselect();
+ sustate_set(SUSTATE_STARTED);
+ break;
+ }
+ case APP_USBD_EVT_STOP_REQ:
+ {
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STOPPED
+ };
+
+ app_usbd_all_iface_deselect();
+ nrf_drv_usbd_stop();
+ sustate_set(SUSTATE_STOPPED);
+
+ /* Send event to all classes */
+ app_usbd_all_call((app_usbd_complex_evt_t const * )&evt_data);
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const *)&evt_data));
+ user_event_state_proc(APP_USBD_EVT_STOPPED);
+ if (app_usbd_sustate_with_requested_hfclk(sustate_get()))
+ {
+ nrf_drv_clock_hfclk_release();
+ }
+
+ break;
+ }
+ case APP_USBD_EVT_HFCLK_READY:
+ {
+ switch(sustate_get())
+ {
+ case SUSTATE_RESUMING:
+ {
+ sustate_set(SUSTATE_ACTIVE);
+ break;
+ }
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ:
+ {
+ sustate_set(SUSTATE_WAKINGUP_WAITING_WREQ);
+ break;
+ }
+ case SUSTATE_WAKINGUP_WAITING_HFCLK:
+ {
+ sustate_set(SUSTATE_ACTIVE);
+ break;
+ }
+ default:
+ break; // Just ignore - it can happen in specyfic situation
+ }
+ break;
+ }
+ case APP_USBD_EVT_SUSPEND_REQ:
+ {
+ /* Suspend request can be only processed when we are in suspending state */
+ if (SUSTATE_SUSPENDING == sustate_get())
+ {
+ if (nrf_drv_usbd_suspend())
+ {
+ sustate_set(SUSTATE_SUSPEND);
+ }
+ }
+ break;
+ }
+ case APP_USBD_EVT_WAKEUP_REQ:
+ {
+ /* Suspend temporary if no suspend function was called from the application.
+ * This makes it possible to generate APP_USBD_EVT_DRV_WUREQ event from the driver */
+ if (sustate_get() == SUSTATE_SUSPENDING)
+ {
+ if (nrf_drv_usbd_suspend())
+ {
+ sustate_set(SUSTATE_SUSPEND);
+ }
+ }
+ if (nrf_drv_usbd_wakeup_req())
+ {
+ sustate_set(SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ);
+ }
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_SOF:
+ {
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+ m_last_frame = p_event->drv_evt.data.sof.framecnt;
+#endif
+ user_event_state_proc(APP_USBD_EVT_DRV_SOF);
+
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_sof_first_get();
+ while (NULL != p_inst)
+ {
+ ret_code_t r = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)p_event);
+ UNUSED_VARIABLE(r);
+ p_inst = app_usbd_class_sof_next_get(p_inst);
+ }
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_RESET:
+ {
+ app_usbd_all_iface_deselect();
+ sustate_set(SUSTATE_ACTIVE);
+ user_event_state_proc(APP_USBD_EVT_DRV_RESET);
+ /* Processing core interface (connected only to EP0) and then all instances from the list */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_DRV_RESUME:
+ {
+ sustate_set(SUSTATE_RESUMING);
+ user_event_state_proc(APP_USBD_EVT_DRV_RESUME);
+ /* Processing core interface (connected only to EP0) and then all instances from the list */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_DRV_WUREQ:
+ {
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_DRV_RESUME
+ };
+ user_event_state_proc(APP_USBD_EVT_DRV_RESUME);
+ /* Processing core interface (connected only to EP0) and then all instances from the list */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const *)&evt_data));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data);
+
+ switch(sustate_get())
+ {
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ:
+ sustate_set(SUSTATE_WAKINGUP_WAITING_HFCLK);
+ break;
+ case SUSTATE_WAKINGUP_WAITING_WREQ:
+ sustate_set(SUSTATE_ACTIVE);
+ break;
+ default:
+ {
+ // This should not happen - but try to recover by setting directly active state
+ NRF_LOG_WARNING("Unexpected state on WUREQ event (%u)", sustate_get());
+ sustate_set(SUSTATE_ACTIVE);
+ }
+ }
+ break;
+ }
+ case APP_USBD_EVT_DRV_SUSPEND:
+ {
+ sustate_set(SUSTATE_SUSPENDING);
+
+ user_event_state_proc(APP_USBD_EVT_DRV_SUSPEND);
+
+ /* Processing all instances from the list and then core interface (connected only to EP0) */
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ break;
+ }
+
+ case APP_USBD_EVT_STATE_CHANGED:
+ {
+ user_event_state_proc(APP_USBD_EVT_STATE_CHANGED);
+ /* Processing all instances from the list and then core interface (connected only to EP0) */
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_SETUP:
+ {
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ {
+ app_usbd_ep_conf_t const * p_ep_conf =
+ app_usbd_ep_conf_access(p_event->drv_evt.data.eptransfer.ep);
+ ASSERT(NULL != p_ep_conf->p_cinst);
+ ASSERT(NULL != p_ep_conf->event_handler);
+
+ if (NRF_SUCCESS != p_ep_conf->event_handler(p_ep_conf->p_cinst,
+ (app_usbd_complex_evt_t const *)p_event))
+ {
+ /* If error returned, every bulk/interrupt endpoint would be stalled */
+ if (!(0 == NRF_USBD_EP_NR_GET(p_event->drv_evt.data.eptransfer.ep) ||
+ NRF_USBD_EPISO_CHECK(p_event->drv_evt.data.eptransfer.ep)))
+ {
+ nrf_drv_usbd_ep_stall(p_event->drv_evt.data.eptransfer.ep);
+ }
+ }
+ break;
+ }
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ case APP_USBD_EVT_POWER_DETECTED:
+ {
+ user_event_state_proc(APP_USBD_EVT_POWER_DETECTED);
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_POWER_REMOVED:
+ {
+ user_event_state_proc(APP_USBD_EVT_POWER_REMOVED);
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_POWER_READY:
+ {
+ user_event_state_proc(APP_USBD_EVT_POWER_READY);
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+#endif
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+bool app_usbd_event_queue_process(void)
+{
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ app_usbd_internal_evt_t sof_event = {
+ .app_evt.type = APP_USBD_EVT_DRV_SOF
+ };
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ static nrf_atfifo_item_get_t cx;
+ static app_usbd_internal_queue_evt_t * p_event_item = NULL;
+ if (NULL == p_event_item)
+ {
+ p_event_item = nrf_atfifo_item_get(m_event_queue, &cx);
+ }
+
+ if (NULL != p_event_item)
+ {
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ if (p_event_item->sof_cnt > 0)
+ {
+ if (p_event_item->start_frame > USBD_FRAMECNTR_FRAMECNTR_Msk)
+ {
+ p_event_item->start_frame = 0;
+ }
+ sof_event.drv_evt.data.sof.framecnt = (p_event_item->start_frame)++;
+ --(p_event_item->sof_cnt);
+ app_usbd_event_execute(&sof_event);
+ return true;
+ }
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+ app_usbd_event_execute(&(p_event_item->evt));
+ UNUSED_RETURN_VALUE(nrf_atfifo_item_free(m_event_queue, &cx));
+ p_event_item = NULL;
+ return true;
+ }
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ else if (m_sof_events_cnt > 0)
+ {
+ CRITICAL_REGION_ENTER();
+ if (m_event_frame > USBD_FRAMECNTR_FRAMECNTR_Msk)
+ {
+ m_event_frame = 0;
+ }
+ sof_event.drv_evt.data.sof.framecnt = m_event_frame++;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_sub_hs(&m_sof_events_cnt, 1));
+ CRITICAL_REGION_EXIT();
+ app_usbd_event_execute(&sof_event);
+ return true;
+ }
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ else
+ {
+ return false;
+ }
+}
+#endif
+
+
+ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != p_cinst->p_class_methods);
+ ASSERT(NULL != p_cinst->p_class_methods->event_handler);
+ ASSERT(NULL == app_usbd_class_data_access(p_cinst)->p_next);
+
+ /* This should be only called if USBD is disabled
+ * We simply assume that USBD is enabled if its interrupts are */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ /* Check if all required endpoints are available
+ * Checking is splitted from setting to avoid situation that anything
+ * is modified and then operation finishes with error */
+ uint8_t iface_idx;
+ app_usbd_class_iface_conf_t const * p_iface;
+
+ iface_idx = 0;
+ while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++)))
+ {
+ uint8_t ep_idx = 0;
+ app_usbd_class_ep_conf_t const * p_ep;
+ while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)))
+ {
+ if (NULL != app_usbd_ep_instance_get(app_usbd_class_ep_address_get(p_ep)))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+ }
+
+ /* Connecting all required endpoints */
+ iface_idx = 0;
+ while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++)))
+ {
+ uint8_t ep_idx = 0;
+ app_usbd_class_ep_conf_t const * p_ep;
+ while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)))
+ {
+ app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_cinst);
+ }
+ }
+
+ /* Adding pointer to this instance to the end of the chain */
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst;
+ while (NULL != (*pp_last))
+ {
+ ASSERT((*pp_last) != p_cinst);
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_next);
+ }
+ (*pp_last) = p_cinst;
+
+ /* Successfully attached */
+ const app_usbd_evt_t evt_data = {.type = APP_USBD_EVT_INST_APPEND };
+ return class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data));
+}
+
+
+ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != p_cinst->p_class_methods);
+ ASSERT(NULL != p_cinst->p_class_methods->event_handler);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+ ret_code_t ret;
+ /* Remove this class from the chain */
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst;
+ while (NULL != (*pp_last))
+ {
+ if ((*pp_last) == p_cinst)
+ {
+ /* Inform class instance that removing process is going to be started */
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_INST_REMOVE
+ };
+ ret = class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ /* Breaking chain */
+ (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_next);
+ app_usbd_class_data_access(p_cinst)->p_next = NULL;
+
+ /* Disconnecting endpoints */
+ uint8_t ep_idx;
+ for (ep_idx = 0; ep_idx < NRF_USBD_EPIN_CNT; ++ep_idx)
+ {
+ nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN(ep_idx);
+ if (app_usbd_ep_instance_get(ep) == p_cinst)
+ {
+ app_usbd_ep_instance_set(ep, NULL);
+ }
+ }
+ for (ep_idx = 0; ep_idx < NRF_USBD_EPOUT_CNT; ++ep_idx)
+ {
+ nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT(ep_idx);
+ if (app_usbd_ep_instance_get(ep) == p_cinst)
+ {
+ app_usbd_ep_instance_set(ep, NULL);
+ }
+ }
+
+ return NRF_SUCCESS;
+ }
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_next);
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+ret_code_t app_usbd_class_remove_all(void)
+{
+ ret_code_t ret = NRF_SUCCESS;
+ while (NULL != m_p_first_cinst)
+ {
+ ret = app_usbd_class_remove(m_p_first_cinst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * const p_cinst,
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_ep_event_handler_t handler)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != handler);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ if (p_cinst != app_usbd_ep_instance_get(ep))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ (app_usbd_ep_conf_access(ep))->event_handler = handler;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != p_cinst->p_class_methods);
+ ASSERT(NULL != p_cinst->p_class_methods->event_handler);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ /* Next SOF event requiring instance have to be null now */
+ ASSERT(NULL == (app_usbd_class_data_access(p_cinst)->p_sof_next));
+
+ /* Adding pointer to this instance to the end of the chain */
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst;
+ while (NULL != (*pp_last))
+ {
+
+ ASSERT((*pp_last) != p_cinst);
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
+ }
+ (*pp_last) = p_cinst;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst;
+ while (NULL != (*pp_last))
+ {
+ if ((*pp_last) == p_cinst)
+ {
+ /* Breaking chain */
+ (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_sof_next);
+ app_usbd_class_data_access(p_cinst)->p_sof_next = NULL;
+
+ return NRF_SUCCESS;
+ }
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+ret_code_t app_usbd_class_rwu_register(app_usbd_class_inst_t const * const p_inst)
+{
+ ASSERT(p_inst != NULL);
+ ++m_rwu_registered_counter;
+ /*Overflow check*/
+ ASSERT(m_rwu_registered_counter != 0);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst)
+{
+ ASSERT(p_inst != NULL);
+ /* Usage validation. If counter is 0 unregister is not possible.*/
+ ASSERT(m_rwu_registered_counter != 0);
+ --m_rwu_registered_counter;
+
+ return NRF_SUCCESS;
+}
+
+bool app_usbd_class_rwu_enabled_check(void)
+{
+ return (m_rwu_registered_counter != 0);
+}
+
+ret_code_t app_usbd_interface_ep_reset(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t iface)
+{
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_cinst);
+
+ app_usbd_class_iface_conf_t const * p_iface = NULL;
+ for (uint8_t j = 0; j < iface_count; ++j)
+ {
+ p_iface = app_usbd_class_iface_get(p_cinst, j);
+ if (app_usbd_class_iface_number_get(p_iface) == iface)
+ {
+ break;
+ }
+ }
+
+ if (p_iface == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ for (uint8_t j = 0; j < ep_count; ++j)
+ {
+ /*Clear stall for every endpoint*/
+ app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j);
+
+ if (!NRF_USBD_EPISO_CHECK(p_ep->address))
+ {
+ nrf_drv_usbd_ep_dtoggle_clear(p_ep->address);
+ nrf_drv_usbd_ep_stall_clear(p_ep->address);
+ }
+
+ }
+
+ return NRF_SUCCESS;
+}
+
+void app_usbd_ep_enable(nrf_drv_usbd_ep_t ep)
+{
+ if (!NRF_USBD_EPISO_CHECK(ep))
+ {
+ nrf_drv_usbd_ep_dtoggle_clear(ep);
+ nrf_drv_usbd_ep_stall_clear(ep);
+ }
+ nrf_drv_usbd_ep_enable(ep);
+}
+
+void app_usbd_ep_disable(nrf_drv_usbd_ep_t ep)
+{
+ nrf_drv_usbd_ep_disable(ep);
+}
+
+
+app_usbd_class_inst_t const * app_usbd_class_first_get(void)
+{
+ return m_p_first_cinst;
+}
+
+app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void)
+{
+ return m_p_first_sof_cinst;
+}
+
+app_usbd_class_inst_t const * app_usbd_iface_find(uint8_t iface, uint8_t * p_iface_idx)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
+ while (p_inst != NULL)
+ {
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
+ /* Iterate over interfaces */
+ for (uint8_t i = 0; i < iface_count; ++i)
+ {
+ app_usbd_class_iface_conf_t const * p_iface;
+ p_iface = app_usbd_class_iface_get(p_inst, i);
+ if (app_usbd_class_iface_number_get(p_iface) == iface)
+ {
+ if (p_iface_idx != NULL)
+ {
+ (*p_iface_idx) = i;
+ }
+ return p_inst;
+ }
+ }
+ p_inst = app_usbd_class_next_get(p_inst);
+ }
+ return NULL;
+}
+
+ret_code_t app_usbd_iface_call(
+ app_usbd_class_inst_t const * const p_class_inst,
+ uint8_t iface_idx,
+ app_usbd_complex_evt_t const * const p_event)
+{
+ UNUSED_PARAMETER(iface_idx);
+ return class_event_handler(p_class_inst, p_event);
+}
+
+ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event)
+{
+ if (NRF_USBD_EP_VALIDATE(ep))
+ {
+ app_usbd_class_inst_t const * p_inst = app_usbd_ep_conf_access(ep)->p_cinst;
+ if (p_inst != NULL)
+ {
+ return class_event_handler(p_inst, p_event);
+ }
+ }
+ return NRF_ERROR_INVALID_ADDR;
+}
+
+void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event)
+{
+ app_usbd_class_inst_t const * p_inst;
+ for (p_inst = app_usbd_class_first_get(); NULL != p_inst;
+ p_inst = app_usbd_class_next_get(p_inst))
+ {
+ UNUSED_RETURN_VALUE(class_event_handler(p_inst, p_event));
+ }
+}
+
+ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event)
+{
+ app_usbd_class_inst_t const * p_inst;
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
+ /* Try to process via every instance */
+ for (p_inst = app_usbd_class_first_get(); NULL != p_inst;
+ p_inst = app_usbd_class_next_get(p_inst))
+ {
+
+ ret = class_event_handler(p_inst, p_event);
+ if (NRF_ERROR_NOT_SUPPORTED != ret)
+ {
+ /* Processing finished */
+ break;
+ }
+ }
+
+ return ret;
+}
+
+ret_code_t app_usbd_ep_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_transfer_t const * const p_transfer)
+{
+ if (!nrf_drv_usbd_ep_enable_check(ep))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_sustate != SUSTATE_ACTIVE)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return nrf_drv_usbd_ep_transfer(ep, p_transfer);
+}
+
+ret_code_t app_usbd_ep_handled_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_handler_desc_t const * const p_handler)
+{
+ if (!nrf_drv_usbd_ep_enable_check(ep))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_sustate != SUSTATE_ACTIVE)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return nrf_drv_usbd_ep_handled_transfer(ep, p_handler);
+}
+
+ret_code_t app_usbd_iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate)
+{
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
+
+ if (p_inst->p_class_methods->iface_select != NULL)
+ {
+ ret = p_inst->p_class_methods->iface_select(p_inst, iface_idx, alternate);
+ }
+
+ if(ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = default_iface_select(p_inst, iface_idx, alternate);
+ }
+ return ret;
+}
+
+void app_usbd_iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ if (p_inst->p_class_methods->iface_deselect != NULL)
+ {
+ p_inst->p_class_methods->iface_deselect(p_inst, iface_idx);
+ }
+ default_iface_deselect(p_inst, iface_idx);
+}
+
+uint8_t app_usbd_iface_selection_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ uint8_t alt = 0;
+ if (p_inst->p_class_methods->iface_selection_get != NULL)
+ {
+ alt = p_inst->p_class_methods->iface_selection_get(p_inst, iface_idx);
+ }
+ return alt;
+}
+
+void app_usbd_all_iface_select_0(void)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
+ while (p_inst != NULL)
+ {
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
+ for (uint8_t i = 0; i < iface_count; ++i)
+ {
+ ret_code_t ret;
+ ret = app_usbd_iface_select(p_inst, i, 0);
+ ASSERT(ret == NRF_SUCCESS);
+ UNUSED_VARIABLE(ret);
+ }
+ p_inst = app_usbd_class_next_get(p_inst);
+ }
+}
+
+void app_usbd_all_iface_deselect(void)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
+ while (p_inst != NULL)
+ {
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
+ for (uint8_t i = 0; i < iface_count; ++i)
+ {
+ app_usbd_iface_deselect(p_inst, i);
+ }
+ p_inst = app_usbd_class_next_get(p_inst);
+ }
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h
new file mode 100644
index 0000000..f63e63c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h
@@ -0,0 +1,745 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_H__
+#define APP_USBD_H__
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_types.h"
+#include "app_usbd_class_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd USB Device high level library
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52840 Module for easy support for any USB device configuration.
+ *
+ * This module manages class instances that would create the USB device,
+ * manages endpoints and interfaces transactions.
+ * @{
+ */
+
+/**
+ * @brief True if SOF timestamping is really provided.
+ *
+ * SOF timestamping is really provided if it was requested and if the logger is enabled.
+ */
+#if ((APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE) && (NRF_LOG_ENABLED))
+#define APP_USBD_PROVIDE_SOF_TIMESTAMP 1
+#else
+#define APP_USBD_PROVIDE_SOF_TIMESTAMP 0
+#endif
+
+/**
+ * @brief SOF event handling modes.
+ */
+#define APP_USBD_SOF_HANDLING_NORMAL_QUEUE 0 //!< Push SOF events into event queue.
+#define APP_USBD_SOF_HANDLING_COMPRESS_QUEUE 1 //!< Compress SOF events.
+#define APP_USBD_SOF_HANDLING_INTERRUPT 2 //!< Handle SOF events in interrupt.
+
+/**
+ * @brief Configuration passed to @ref app_usbd_init.
+ */
+typedef struct {
+#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
+ /**
+ * @brief User defined event handler.
+ *
+ * This function is called on every event from the interrupt.
+ * It is prepared for external user function that would queue events to be processed
+ * from the main context.
+ * It should be used with operating systems with its own implementation of the queue.
+ *
+ * @param p_event The event structure pointer.
+ *
+ * @note This field is available only when USB internal queue is disabled
+ * (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
+ */
+ void (*ev_handler)(app_usbd_internal_evt_t const * const p_event);
+#endif
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+ /**
+ * @brief User defined event handler.
+ *
+ * This function is called on every event from the interrupt.
+ *
+ * @param p_event The event structure pointer.
+ * @param queued The event is visible in the queue.
+ * If queue conflict is detected the event might not be accessible inside queue
+ * until all write operations finish.
+ * See @ref nrf_atfifo for more details.
+ *
+ * @note This field is available only when USBD internal queue is configured
+ * (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
+ *
+ * @note If is set to NULL no event would be called from interrupt.
+ * @note This function is called before event is processed.
+ * It means that if the event type is @ref APP_USBD_EVT_DRV_SETUP,
+ * there would not be setup field present in the event structure.
+ */
+ void (*ev_isr_handler)(app_usbd_internal_evt_t const * const p_event, bool queued);
+#endif
+
+ /**
+ * @brief User defined event processor
+ *
+ * This function is called while state event is processed.
+ *
+ * * @note This field is available only when USBD internal queue is configured
+ * (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
+ *
+ * @param event Event type.
+ * Only following events are sent into this function:
+ * - APP_USBD_EVT_DRV_SOF
+ * - APP_USBD_EVT_DRV_RESET - Note that it also exits suspend
+ * - APP_USBD_EVT_DRV_SUSPEND
+ * - APP_USBD_EVT_DRV_RESUME - It is also generated when remote wakeup is generated
+ * - APP_USBD_EVT_START
+ * - APP_USBD_EVT_STOP
+ * - APP_USBD_EVT_STATE_CHANGED
+ */
+ void (*ev_state_proc)(app_usbd_event_type_t event);
+
+ /**
+ * @brief SOF processing required by the user event processing
+ *
+ * This flag would enable SOF processing for the user events regardless of the fact if any
+ * of the implemented class requires SOF event.
+ *
+ * @note SOF event would be enabled anyway if any of the appended class requires SOF processing.
+ */
+ bool enable_sof;
+} app_usbd_config_t;
+
+
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Timestamp function for the logger.
+ *
+ * @return Current frame number taken directly from the last processed SOF.
+ */
+uint32_t app_usbd_sof_timestamp_get(void);
+#endif
+
+/**
+ * @brief USB library initialization.
+ *
+ * Call this function before any configuration or class attachment.
+ * USBD peripheral would be ready to accept commands, and library would be ready,
+ * but it would not be connected to the bus.
+ * Call @ref app_usbd_enable to enable USBD communication with the host.
+ *
+ * @param p_config Configuration. NULL pointer might be passed here and default
+ * configuration will be applied then.
+ */
+ret_code_t app_usbd_init(app_usbd_config_t const * p_config);
+
+/**
+ * @brief USB library un-initialization
+ *
+ * @note Currently not supported
+ */
+ret_code_t app_usbd_uninit(void);
+
+#if (APP_USBD_CONFIG_POWER_EVENTS_PROCESS) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Function to start USB related power events processing
+ *
+ * This function should be called after @ref app_usbd_init and after all the
+ * required classes were appended (@ref app_usbd_class_append).
+ *
+ * @retval NRF_SUCCESS Power events successfully initialized
+ * @retval NRF_ERROR_INVALID_STATE The state of the driver does not allow to enable
+ * the power events processing.
+ */
+ret_code_t app_usbd_power_events_enable(void);
+#endif
+
+/**
+ * @brief Enable USBD
+ *
+ * USBD is enabled.
+ * Since now the high frequency clock may be requested when USB RESET would be detected.
+ */
+void app_usbd_enable(void);
+
+/**
+ * @brief Disable USBD
+ *
+ * Disabled USDB peripheral cannot be accessed but also stops requesting
+ * High Frequency clock and releases power regulator.
+ *
+ * @note This function cannot be called when USB is started. Stop it first.
+ */
+void app_usbd_disable(void);
+
+/**
+ * @brief Request USBD to start
+ *
+ * The function sends start request to the event queue.
+ * If the queue is enabled (@ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) it would be processed
+ * when the queue is processed.
+ * If queue is disabled it would be processed immediately inside this function.
+ * It means that if queue is disabled this function cannot be called from interrupt with priority
+ * higher than USB interrupt.
+ *
+ * When start is processed it would:
+ * 1. Start library.
+ * 2. Enable interrupts.
+ * 3. Enable USB pull-ups.
+ *
+ * @note
+ * In some specific circumstances the library can be left not started and this function would
+ * silently exit.
+ * This may happen if some glitches appears on USB power line or if the plug was disconnected before
+ * whole starting process finishes.
+ * User would get the event from POWER peripheral then.
+ * Also no @ref APP_USBD_EVT_STARTED event would be generated to the classes and user event handler.
+ * For the safe code it is recommended to wait for @ref APP_USBD_EVT_STARTED event if anything
+ * has to be initialized after USB driver is started (just before enabling the interrupts).
+ * If library is properly started the @ref APP_USBD_EVT_STARTED event passed to the user handler
+ * from this function body.
+ */
+void app_usbd_start(void);
+
+/**
+ * @brief Stop USB to work
+ *
+ * The function sends stop request to the event queue.
+ * If the queue is enabled (@ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) it would be processed
+ * when the queue is processed.
+ * If queue is disabled it would be processed immediately inside this function.
+ * It means that if queue is disabled this function cannot be called from interrupt with priority
+ * higher than USB interrupt.
+ *
+ * When the event is processed interrupts and USB pull-ups are disabled.
+ * The peripheral itself is left enabled so it can be programmed,
+ * but a HOST sees it as a peripheral disconnection.
+ *
+ * @note
+ * If the library is not started when this function is called it exits silently - also
+ * no @ref APP_USBD_EVT_STOPPED is generated.
+ */
+void app_usbd_stop(void);
+
+/**
+ * @brief Request library to suspend
+ *
+ * This function send suspend request to the event queue.
+ *
+ * @note This function should only be called after @ref APP_USBD_EVT_DRV_SUSPEND os received.
+ * Internal suspend request processing would give no effect if the bus is not in suspend state.
+ */
+void app_usbd_suspend_req(void);
+
+/**
+ * @brief Request library to wake-up
+ *
+ * This function send wakeup request to the event queue.
+ *
+ * @note Calling this function does not mean that peripheral is active - the wakeup request is sent
+ * into message queue and needs to be processed.
+ *
+ * @retval true Wakeup generation has been started.
+ * @retval false No wakeup would be generated becouse it is disabled by the host.
+ */
+bool app_usbd_wakeup_req(void);
+
+/**
+ * @brief Get information whether there is an active connection.
+ *
+ * Function to check if the communication with the bus is possible.
+ *
+ * @retval true The bus is active.
+ * @retval false There is no connection or bus is suspended.
+ */
+bool app_usbd_active_check(void);
+
+/**
+ * @brief USBD event processor
+ *
+ * Function to be called on each event to be processed by the library.
+ */
+void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event);
+
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Function that process events from the queue
+ *
+ * @note This function calls @ref app_usbd_event_execute internally.
+ *
+ * @retval true Event was processed
+ * @retval false The event queue is empty
+ */
+bool app_usbd_event_queue_process(void);
+#endif
+
+/**
+ * @brief Add class instance
+ *
+ * This function connects given instance into internal class instance chain and
+ * into all required endpoints.
+ * The instance event handler would be connected into endpoint by default,
+ * but this can be overwritten by @ref app_usbd_ep_handler_set.
+ *
+ * After successful attachment @ref APP_USBD_EVT_INST_APPEND would be passed to class instance.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @param[in,out] p_cinst Instance to connect. Chain data would be written into writable instance data.
+ */
+ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Remove class instance
+ *
+ * Instance is removed from instance chain.
+ * Instance and event handlers are removed also from endpoints.
+ * Endpoints used by by the class instance are left disabled.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @param p_cinst Instance pointer to remove.
+ *
+ * @retval NRF_SUCCESS Instance successfully removed.
+ * @retval NRF_ERROR_NOT_FOUND Instance not found in the instance chain.
+ */
+ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Remove all class instances
+ *
+ * This function basically calls @ref app_usbd_class_remove
+ * on instances chain as long as there is any element left.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @sa app_usbd_class_remove
+ *
+ * @return Is should always return @ref NRF_SUCCESS.
+ * Any error value returned would mean there is an error inside the library.
+ */
+ret_code_t app_usbd_class_remove_all(void);
+
+/**
+ * @brief Change endpoint handler
+ *
+ * This function may be called for the endpoint only if the class instance is
+ * already properly attached by the @ref app_usbd_class_append function.
+ *
+ * The endpoint event handler function can be only overwritten by the class instance
+ * that was connected into the endpoint.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @param[in] p_cinst Instance of a class that wish to set new event handler.
+ * It has to match currently configured instance for the selected endpoint.
+ * In other situation error would be returned.
+ * @param[in] ep Endpoint address to configure.
+ * @param[in] handler Event handler function to set.
+ *
+ * @retval NRF_SUCCESS New handler successfully set
+ * @retval NRF_ERROR_INVALID_PARAM p_cinst is not the same as currently set for the endpoint
+ */
+ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * p_cinst,
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_ep_event_handler_t handler);
+
+/**
+ * @brief Register class instance as the one that requires SOF events
+ *
+ * This function should be called in reaction on APP_USBD_EVT_INST_APPEND event.
+ * Connect the class instance to the list of instances that requires SOF processing.
+ * If none of the appended instances requires SOF event - it is disabled.
+ *
+ * @param p_cinst Instance that requires SOF event.
+ *
+ * @retval NRF_SUCCESS Instance linked into SOF processing list.
+ *
+ * @sa app_usbd_class_sof_unregister
+ */
+ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Unregister class instance from SOF processing instances list
+ *
+ * Every class that calls @ref app_usbd_class_sof_register have to call also unregistering function
+ * in reaction to @ref APP_USBD_EVT_INST_REMOVE event.
+ *
+ * @param p_cinst Instance to be unregistered from SOF event processing list.
+ *
+ * @retval NRF_SUCCESS Instance linked into SOF processing list.
+ * @retval NRF_ERROR_NOT_FOUND Instance not found in the SOF processing list.
+ *
+ * @sa app_usbd_class_sof_register
+ */
+ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Register class on remote wake-up feature
+ *
+ * @param[in] p_inst Instance of the class
+ *
+ * @retval NRF_SUCCESS Instance that requires remote wake-up registered
+ */
+ret_code_t app_usbd_class_rwu_register(app_usbd_class_inst_t const * const p_inst);
+
+/**
+ * @brief Unregister class from remote wake-up feature
+ *
+ * @param[in] p_inst Instance of the class
+ *
+ * @retval NRF_SUCCESS Instance that requires remote wake-up removed
+ */
+ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst);
+
+/**
+ * @brief Check if there is any class with remote wakeup
+ *
+ * The function checks internal registered class with remote wakeup counter.
+ *
+ * @sa app_usbd_class_rwu_register, app_usbd_class_rwu_unregister
+ *
+ * @retval true The remote wakeup functionality is required by some class instance
+ * @retval false There is no class instance that requires wakeup functionality
+ */
+bool app_usbd_class_rwu_enabled_check(void);
+
+/**
+ * @brief Find a specified descriptor
+ *
+ * @param[in] p_cinst Class instance
+ * @param[in] desc_type Descriptor type @ref app_usbd_descriptor_t
+ * @param[in] desc_index Descriptor index
+ * @param[out] p_desc Pointer to escriptor
+ * @param[out] p_desc_len Length of descriptor
+ *
+ * @return Standard error code @ref ret_code_t
+ * @retval NRF_SUCCESS descriptor successfully found
+ * @retval NRF_ERROR_NOT_FOUND descriptor not found
+ * */
+ret_code_t app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t desc_type,
+ uint8_t desc_index,
+ uint8_t * p_desc,
+ size_t * p_desc_len);
+
+/**
+ * @brief Standard set interface request handle
+ *
+ * This function should be called when processing SET_INTERFACE request.
+ *
+ * @param[in] p_cinst Instance of a class
+ * @param[in] iface Interface number
+ *
+ * @return Standard error code
+ *
+ * @note Selected interface to reset has to be part of given class.
+ * In other case
+ * */
+ret_code_t app_usbd_interface_ep_reset(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t iface);
+
+
+/**
+ * @brief Enable selected endpoint
+ *
+ * Selected endpoint is enabled and cleared.
+ *
+ * @param ep Endpoint number
+ */
+void app_usbd_ep_enable(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Disable selected endpoint
+ *
+ * @param ep Endpoint number
+ */
+void app_usbd_ep_disable(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @name Iterate through classes lists
+ *
+ * Functions that helps to iterate through internally chained classes.
+ * @{
+ */
+ /**
+ * @brief Get first class instance in the list
+ *
+ * Get first instance from the list of active class instances.
+ * That instance may be used then in @ref app_usbd_class_next_get function.
+ *
+ * @return First instance in the list or NULL if there are no instances available.
+ */
+ app_usbd_class_inst_t const * app_usbd_class_first_get(void);
+
+ /**
+ * @brief Get next instance in the list
+ *
+ * Get the next instance from the list of active instances.
+ * Used to iterate through all instances.
+ *
+ * @param[in] p_cinst The current instance from with next one is required.
+ *
+ * @return Next instance to the given one or NULL if there is no more instances in the list.
+ */
+ static inline app_usbd_class_inst_t const * app_usbd_class_next_get(
+ app_usbd_class_inst_t const * const p_cinst)
+ {
+ ASSERT(NULL != p_cinst);
+ return app_usbd_class_data_access(p_cinst)->p_next;
+ }
+
+ /**
+ * @brief Get first instance in SOF list
+ *
+ * Start iteration through the list of instances that requires SOF event processing.
+ *
+ * @return First instance in the list or NULL if the list is empty
+ *
+ * @sa app_usbd_class_first_get
+ */
+ app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void);
+
+ /**
+ * @brief Get next instance in the SOF list
+ *
+ * Get the next instance from the list of instances requiring SOF event processing.
+ * Used to iterate through all SOF instances.
+ *
+ * @param p_cinst The current instance from with next one is required.
+ *
+ * @return Next instance to the given one or NULL if there is no more instances in the list.
+ */
+ static inline app_usbd_class_inst_t const * app_usbd_class_sof_next_get(
+ app_usbd_class_inst_t const * const p_cinst)
+ {
+ ASSERT(NULL != p_cinst);
+ return app_usbd_class_data_access(p_cinst)->p_sof_next;
+ }
+/** @} */
+
+/**
+ * @brief Search for selected interface
+ *
+ * Function searches for the given interface number and returns the class that contains it.
+ * Optionally it can return interface index inside class instance.
+ *
+ * @param[in] iface Interface number
+ * @param[out] p_iface_idx Pointer to a variable that would hold interface index inside returned
+ * class instance.
+ *
+ * @return Pointer to the class structure that cointain given interface or NULL if not found.
+ */
+app_usbd_class_inst_t const * app_usbd_iface_find(uint8_t iface, uint8_t * p_iface_idx);
+
+
+/**
+ * @name Communicate with interfaces, endpoints and instances inside usbd library
+ *
+ * @{
+ */
+
+ /**
+ * @brief Call interface event handler
+ *
+ * Call event handler for selected interface.
+ * @param[in,out] p_class_inst Class instance that holds selected interface
+ * @param[in] iface_idx Index of the interface in class structure
+ * @param[in] p_event Event structure to be processed
+ *
+ * @return Operation status
+ */
+ ret_code_t app_usbd_iface_call(
+ app_usbd_class_inst_t const * const p_class_inst,
+ uint8_t iface_idx,
+ app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Call endpoint event handler
+ *
+ * Call event handler for the selected endpoint.
+ * @param[in] ep Endpoint number
+ * @param[in] p_event Event structure to send
+ *
+ * @return Operation status
+ */
+ ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Auxiliary function that process event by every instance in the list
+ *
+ * This function ignores the result of called handler.
+ *
+ * @param p_event Event to pass to every instance
+ */
+ void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Call interface event handlers and stop when served
+ *
+ * Call event handlers from instances as long as we get result different than @ref NRF_ERROR_NOT_SUPPORTED
+ * @param[in] p_event Event structure to send
+ *
+ * @return Operation status or @ref NRF_ERROR_NOT_SUPPORTED if none of instances in the list can support given event.
+ */
+ ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event);
+/** @} */
+
+/**
+ * @brief Endpoint transfer
+ *
+ * @param ep Endpoint number
+ * @param p_transfer Description of the transfer to be performed.
+ * The direction of the transfer is determined by the
+ * endpoint number.
+ *
+ * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
+ * data transfer on the endpoint.
+ * @return Values returned by @ref nrf_drv_usbd_ep_transfer
+ *
+ * @sa app_usbd_ep_handled_transfer
+ */
+ret_code_t app_usbd_ep_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_transfer_t const * const p_transfer);
+
+/**
+ * @brief Set up an endpoint handled transfer.
+ *
+ * Configures a transfer handled by the feedback function.
+ *
+ * @param ep Endpoint number.
+ * @param p_handler Function called when the next chunk of data is requested.
+ *
+ * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
+ * data transfer on the endpoint.
+ * @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer.
+ */
+ret_code_t app_usbd_ep_handled_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_handler_desc_t const * const p_handler);
+
+
+/**
+ * @brief Select interface
+ *
+ * Select the given interface.
+ * This function calls class interface selection function or default
+ * interface selection function.
+ *
+ * After calling this function interface should be functional.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ * @param[in] alternate Alternate setting that should be selected
+ *
+ * @return Standard Error code
+ */
+ret_code_t app_usbd_iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate);
+
+
+/**
+ * @brief Deselect interface
+ *
+ * Disable the given interface.
+ * This function calls class interface deselection function or
+ * default interface selection function.
+ *
+ * After calling this function all the endpoints from the interface
+ * have to be disabled.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ */
+void app_usbd_iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx);
+
+/**
+ * @brief Get selected interface
+ *
+ * Function retieves currently selected interface.
+ * If the class contains @ref app_usbd_class_methods_t::iface_selection_get it is called.
+ * It it does not contain this function this function would return default, 0 value.
+ *
+ * @param[in] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ *
+ * @return Selected alternate interface setting
+ */
+uint8_t app_usbd_iface_selection_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx);
+
+/**
+ * @brief Select alternate configuration 0 for all interfaces
+ *
+ * Auxiliary function that clears settings for all interfaces leaving them enabled.
+ */
+void app_usbd_all_iface_select_0(void);
+
+/**
+ * @brief Deselect all interfaces
+ *
+ * Auxiliary function to disable all interfaces.
+ */
+void app_usbd_all_iface_deselect(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h
new file mode 100644
index 0000000..672ab28
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h
@@ -0,0 +1,1094 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_CLASS_BASE_H__
+#define APP_USBD_CLASS_BASE_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "app_usbd_types.h"
+#include "nrf_drv_usbd.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_class_base USBD Class Base module
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 The base for any class instance is defined in this module.
+ *
+ * @details Any class instance must start from base class instance structure.
+ * This makes them compatible with USBD library independently of the
+ * implementation details.
+ * @{
+ */
+
+/**
+ * @brief Endpoint configuration
+ */
+typedef struct
+{
+ nrf_drv_usbd_ep_t address; //!< Endpoint address
+} app_usbd_class_ep_conf_t;
+
+/**
+ * @brief Interface configuration
+ */
+typedef struct
+{
+ uint8_t number; //!< Interface number
+ uint8_t ep_cnt; //!< Endpoint number
+ uint8_t ep_offset; //!< Offset of the first endpoint
+ /**< Offset in bytes of the first endpoint.
+ * The offset is calculated from the address of this interface structure
+ */
+} app_usbd_class_iface_conf_t;
+
+/**
+ * @brief Instance variable data
+ */
+typedef struct
+{
+ app_usbd_class_inst_t const * p_next; //!< Pointer to the next instance
+ app_usbd_class_inst_t const * p_sof_next; //!< Pointer to the next SOF event requiring instance
+} app_usbd_class_data_t;
+
+/**
+ * @brief Class descriptor context
+ */
+typedef struct
+{
+ uint32_t line; //!< Number of line to resume writing descriptors from
+ uint8_t data_buffer; //!< Data from last call of feeder
+} app_usbd_class_descriptor_ctx_t;
+
+/**
+ * @brief Class descriptor state
+ */
+typedef struct
+{
+ uint8_t * p_buffer; //!< Pointer to buffer
+ uint32_t current_size; //!< Current size of descriptor
+ uint32_t maximum_size; //!< Maximum size of descriptor
+ app_usbd_class_descriptor_ctx_t * p_context; //!< Pointer to context
+} app_usbd_class_descriptor_state_t;
+
+/**
+ * @brief Class interface function set
+ * */
+typedef struct {
+ /**
+ * @brief Instance callback function
+ *
+ * The function used by every class instance.
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] p_event Event to process
+ *
+ * @return Standard error code
+ *
+ * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED
+ */
+ ret_code_t (* event_handler)(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Instance feed descriptors
+ *
+ * Feeds whole descriptor of the instance
+ * @param[in] p_ctx Class descriptor context
+ * @param[in,out] p_inst Instance of the class
+ * @param[out] p_buff Buffer for descriptor
+ * @param[in] max_size Requested size of the descriptor
+ *
+ * @return True if not finished feeding the descriptor, false if done
+ */
+ bool (* feed_descriptors)(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size);
+
+
+ /**
+ * @brief Select interface
+ *
+ * Function called when class interface has to be selected.
+ *
+ * This function would be called for every interface when:
+ * - SET_INTERFACE command is processed by the default handler
+ * - SET_CONFIG(1) command is processed by the default handler
+ *
+ * @note Remember to disable all the endpoints that are not used
+ * in the selected configuration.
+ * @note If this function pointer is NULL default procedure would
+ * just enable all the interface endpoints and selecting
+ * alternate configurations other than 0 would generate error.
+ * @note Calling the function with alternate setting 0 has to always succeed.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ * @param[in] alternate Alternate setting that should be selected
+ *
+ * @return Function has to return @ref NRF_SUCCESS when it has successfully proceed
+ * interface selection.
+ * If it returns @ref NRF_ERROR_NOT_SUPPORTED, default function would be used
+ * to proceed the request - just like there would be NULL pointer in this field.
+ * Any other kind of error would make library to STALL the request.
+ */
+ ret_code_t (* iface_select)(app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate);
+
+ /**
+ * @brief Deselect interface
+ *
+ * Function called when the class interface has to be deselected.
+ *
+ * This function would be called for every interface when:
+ * - Library start internal event is processed by the default handler
+ * - RESET event is processed by the default handler
+ * - SET_ADDRESS is processed by the default handler
+ * - SET_CONFIG(0) is processed by the default handler
+ *
+ * @note Just after this function is called all the interface
+ * endpoints would be disabled.
+ * This function does not has to take care about it.
+ * @note If this function pointer is NULL default procedure would
+ * just disable all the interface endpoints.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ */
+ void (* iface_deselect)(app_usbd_class_inst_t const * const p_inst, uint8_t iface_idx);
+
+ /**
+ * @brief Get current interface
+ *
+ * Function called when class interface has to return its alternate settings
+ * in reaction on GET_INTERFACE command.
+ * It should be defined in a pair with @ref app_usbd_class_methods_t::iface_select.
+ *
+ * @param[in] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ *
+ * @return Current alternate setting of the selected interface.
+ *
+ * @note For the classes that support this function, when an interface that has not alternate
+ * configurations has been selected this function has to return 0 - default alternate setting.
+ *
+ * @note If this function pointer it NULL default procedure would return alternate interface
+ * value 0.
+ */
+ uint8_t (* iface_selection_get)(app_usbd_class_inst_t const * const p_inst, uint8_t iface_idx);
+
+} app_usbd_class_methods_t;
+
+/**
+ * @brief The instance structure itself
+ *
+ * The structure of base class instance
+ */
+struct app_usbd_class_inst_s
+{
+ app_usbd_class_data_t * p_data; //!< Pointer to non-constant data
+ app_usbd_class_methods_t const * p_class_methods; //!< Class interface methods
+ struct
+ {
+ uint8_t cnt; //!< Number of defined interfaces
+ uint8_t config[]; //!< Interface configuration data followed by endpoint data
+ } iface; //!< Interface structure
+};
+
+
+/**
+ * @brief Get total number of interfaces
+ *
+ *
+ */
+static inline uint8_t app_usbd_class_iface_count_get(app_usbd_class_inst_t const * const p_inst)
+{
+ return p_inst->iface.cnt;
+}
+
+/**
+ * @brief Interface accessing function
+ *
+ * Get interface pointer.
+ * Interfaces creates continuous array in the memory so it is possible to get
+ * interface with index 0 and the just iterate to the next one.
+ *
+ * @param p_inst Pointer to the class instance
+ * @param iface_idx Index of the instance to get.
+ * This is not the interface identifier.
+ * Technically it is the index of the interface in the class description array.
+ * @return Pointer to the interface configuration parameters or NULL if given index is out of interface scope for given class.
+ */
+static inline app_usbd_class_iface_conf_t const * app_usbd_class_iface_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ ASSERT(NULL != p_inst);
+ if (iface_idx >= (app_usbd_class_iface_count_get(p_inst)))
+ {
+ return NULL;
+ }
+
+ app_usbd_class_iface_conf_t const * p_interface =
+ (app_usbd_class_iface_conf_t const * )(p_inst->iface.config);
+ return &(p_interface[iface_idx]);
+}
+
+/**
+ * @brief Get interface number
+ *
+ * @param p_iface Pointer to interface structure
+ *
+ * @return Interface number from interface configuration structure
+ */
+static inline uint8_t app_usbd_class_iface_number_get(
+ app_usbd_class_iface_conf_t const * const p_iface)
+{
+ return p_iface->number;
+}
+
+/**
+ * @brief Get number of endpoints in interface
+ *
+ * @param p_iface Pointer to interface structure
+ *
+ * @return Number of endpoints used by given interface
+ */
+static inline uint8_t app_usbd_class_iface_ep_count_get(
+ app_usbd_class_iface_conf_t const * const p_iface)
+{
+ return p_iface->ep_cnt;
+}
+
+/**
+ * @brief Interface Endpoint accessing function
+ *
+ * @param p_iface Interface configuration pointer
+ * @param ep_idx Endpoint index
+ *
+ * @return Endpoint information structure pointer or NULL if given index is outside of endpoints for selected interface.
+ *
+ * @sa app_usbd_class_iface_get
+ */
+static inline app_usbd_class_ep_conf_t const * app_usbd_class_iface_ep_get(
+ app_usbd_class_iface_conf_t const * const p_iface,
+ uint8_t ep_idx)
+{
+ ASSERT(NULL != p_iface);
+ if (ep_idx >= p_iface->ep_cnt)
+ {
+ return NULL;
+ }
+
+ app_usbd_class_ep_conf_t const * p_ep =
+ (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset);
+ return &(p_ep[ep_idx]);
+}
+
+/**
+ * @brief Translate endpoint address to class index
+ *
+ * @param p_iface Interface configuration pointer
+ * @param ep_address Endpoint address
+ *
+ * @return Endpoint index or number of endpoints if not found
+ *
+ */
+static inline uint8_t app_usbd_class_iface_ep_idx_get(
+ app_usbd_class_iface_conf_t const * const p_iface,
+ nrf_drv_usbd_ep_t ep_address)
+{
+ ASSERT(NULL != p_iface);
+ app_usbd_class_ep_conf_t const * p_ep =
+ (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset);
+
+ uint8_t i;
+ for (i = 0; i < p_iface->ep_cnt; ++i)
+ {
+ if (ep_address == p_ep[i].address)
+ {
+ break;
+ }
+ }
+
+ return i;
+}
+
+/**
+ * @brief Get the selected endpoint address
+ *
+ * @param p_ep Endpoint configuration structure
+ *
+ * @return Endpoint address
+ */
+static inline nrf_drv_usbd_ep_t app_usbd_class_ep_address_get(app_usbd_class_ep_conf_t const * p_ep)
+{
+ return (nrf_drv_usbd_ep_t)p_ep->address;
+}
+
+/**
+ * @brief Get the pointer to the writable instance data
+ *
+ * @param p_inst Instance pointer
+ * @return Pointer to writable instance data
+ */
+static inline app_usbd_class_data_t * app_usbd_class_data_access(
+ app_usbd_class_inst_t const * const p_inst)
+{
+ return p_inst->p_data;
+}
+
+/**
+ * @name Internal macros for argument mapping
+ *
+ * Functions to be used as a mapping macro for @ref MACRO_MAP, @ref MACRO_MAP_FOR or @ref MACRO_MAP_FOR_PARAM
+ * @{
+ */
+ /**
+ * @brief Count the number of endpoints in given configuration
+ *
+ * Config should be given as a interface configuration in a brackets:
+ * @code
+ * (interface_nr, ep1, ep2, ep3)
+ * @endcode
+ * Number of endpoints may vary from 0 to a few (technically up to 16, but it seems not to make sense to use more than 4).
+ * Interface number is always present.
+ *
+ * @param iface_config Single interface configuration (in brackets)
+ *
+ * @return Number of endpoints in interface. This is computed value - can be used by compiler but not by preprocessor.
+ */
+ #define APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) \
+ (NUM_VA_ARGS(BRACKET_EXTRACT(iface_config)) - 1)
+
+ /**
+ * @brief Adds the number of endpoints in given config to the current value
+ *
+ * This is basically @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ with plus sign added.
+ *
+ * @param iface_config See parameters documentation in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_
+ *
+ * @return Plus sign followed by number of endpoints in interface.
+ *
+ * @sa APP_USBD_CLASS_CONF_IFACE_EP_COUNT_
+ */
+ #define APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_(iface_config) \
+ + APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config)
+
+ /**
+ * @brief Create variable for endpoint
+ */
+
+ /**
+ * @brief Extract endpoints given interface configuration
+ *
+ * This macro gets single endpoint configuration and extracts all the endpoints.
+ * It also adds comma on the end of extracted endpoints.
+ * This way when this macro is called few times it generates nice list of all endpoints
+ * that may be used to array initialization.
+ *
+ * @param iface_config Single interface configuration in brackets.
+ * The format should be similar like described in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_.
+ */
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_(iface_config) \
+ CONCAT_2(APP_USBD_CLASS_IFACE_EP_EXTRACT_, \
+ NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \
+ (BRACKET_EXTRACT(iface_config))
+
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_
+ *
+ * This macro is called when interface has no endpoints
+ */
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_0(iface_nr)
+
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_
+ *
+ * This macro is called when interface has at least one endpoint
+ */
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1(...) \
+ APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(__VA_ARGS__)
+
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(iface_nr, ...) \
+ MACRO_MAP_REC(PARAM_CBRACE, __VA_ARGS__)
+
+ /**
+ * @brief Generate configuration for single interface
+ *
+ * This macro extract configuration for single interface.
+ * The configuration is inside curly brackets and comma is added on the end.
+ * This mean it can be directly used to init array of interface configurations.
+ *
+ * @param iface_config Single interface configuration
+ * @param N Currently processed configuration
+ * @param iface_configs All interfaces configuration in brackets
+ */
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_(iface_config, N, iface_configs) \
+ CONCAT_2(APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \
+ NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \
+ (N, iface_configs, BRACKET_EXTRACT(iface_config))
+
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_x(iface_config, N, iface_configs) \
+ [N] = !!!iface_config!!!
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_
+ *
+ * This macro is called when interface has no endpoints
+ */
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0(N, iface_configs, iface_nr) \
+ APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr)
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) \
+ { .number = iface_nr, .ep_cnt = 0, .ep_offset = 0 },
+
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_
+ *
+ * This macro is called when interface has at last one endpoint
+ */
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1(N, iface_configs, ...) \
+ APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, __VA_ARGS__)
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, iface_nr, ...) \
+ { .number = iface_nr, .ep_cnt = NUM_VA_ARGS(__VA_ARGS__), \
+ .ep_offset = APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) * \
+ sizeof(app_usbd_class_ep_conf_t) \
+ + ((NUM_VA_ARGS(BRACKET_EXTRACT(iface_configs)) - N) * \
+ sizeof(app_usbd_class_iface_conf_t)) \
+ },
+
+/** @} */
+
+
+/**
+ * @name Macros that uses mapping macros internally
+ *
+ * Auxiliary macros that uses mapping macros to make some calculations or realize other functionality.
+ * Mapped here for easier unit testing and to hide complex mapping functions calling.
+ * @{
+ */
+
+/**
+ * @brief Count total number of endpoints
+ *
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return The equation to calculate the number of endpoints by compiler.
+ */
+#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(iface_configs) \
+ (0 MACRO_MAP(APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs)))
+
+/**
+ * @brief Count total number of endpoint up-to interface index
+ *
+ * The version of @ref APP_USBD_CLASS_CONF_TOTAL_EP_COUNT macro which takes the
+ * number of interfaces to analyze.
+ *
+ * @param N Number of interfaces to analyze
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return The equation to calculate the number of endpoints by compiler.
+ */
+#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) \
+ (0 MACRO_MAP_N(N, APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs)))
+
+/**
+ * @brief Extract configurations for interfaces
+ *
+ * This macro extracts the configurations for every interface.
+ * Basically uses the @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ macro on every
+ * configuration found.
+ *
+ * This should generate interface configuration initialization data
+ * in comma separated initializers in curly braces.
+ *
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return Comma separated initialization data for all interfaces.
+ */
+/*lint -emacro( (40), APP_USBD_CLASS_IFACES_CONFIG_EXTRACT) */
+#define APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(iface_configs) \
+ MACRO_MAP_FOR_PARAM(iface_configs, \
+ APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \
+ BRACKET_EXTRACT(iface_configs))
+
+/**
+ * @brief Extract all endpoints
+ *
+ * Macro that extracts all endpoints from every interface
+ *
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return Comma separated list of endpoints
+ */
+/*lint -emacro( (40), APP_USBD_CLASS_IFACES_EP_EXTRACT) */
+#define APP_USBD_CLASS_IFACES_EP_EXTRACT(iface_configs) \
+ MACRO_MAP(APP_USBD_CLASS_IFACE_EP_EXTRACT_, BRACKET_EXTRACT(iface_configs))
+
+
+/** @} */
+
+
+/**
+ * @brief USBD instance of class mnemonic
+ *
+ * Macro that generates mnemonic for the name of the structure that describes instance for selected class.
+ *
+ * @param type_name The name of the instance without _t postfix
+ *
+ * @return The name with the right postfix to create the name for the type for the class.
+ */
+#define APP_USBD_CLASS_INSTANCE_TYPE(type_name) CONCAT_2(type_name, _t)
+
+/**
+ * @brief USBD data for instance class mnemonic
+ *
+ * The mnemonic of the variable type that holds writable part of the class instance.
+ *
+ * @param type_name The name of the instance without _t postfix
+ *
+ * @return The name with the right postfix to create the name for the data type for the class.
+ */
+#define APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(type_name, _data_t)
+
+/**
+ * @brief Declare class specific member of class instance
+ *
+ * @param type Type of the attached class configuration.
+ *
+ * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
+ */
+#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) type class_part;
+
+/**
+ * @brief Used if there is no class specific configuration
+ *
+ * This constant can be used if there is no specific configuration inside created instance
+ *
+ * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
+ */
+#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+
+/**
+ * @brief Declare class specific member of class data
+ *
+ * @param type Type of the attached class data.
+ *
+ * @sa APP_USBD_CLASS_DATA_TYPEDEF
+ */
+#define APP_USBD_CLASS_DATA_SPECIFIC_DEC(type) APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type)
+
+/**
+ * @brief Used if there is no class specific data
+ *
+ * This constant can be used if there is no specific writable data inside created instance
+ *
+ * @sa APP_USBD_CLASS_DATA_TYPEDEF
+ */
+#define APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+
+
+
+
+/**
+ * @brief Instance structure declaration
+ *
+ * The macro that declares a variable type that would be used to store given class instance.
+ * Class instance stores all the data from @ref app_usbd_class_inst_t and overlaid data for specified class.
+ *
+ * The structure of interface configuration data:
+ * @code
+ * (
+ * (iface1_nr, (ep1, ep2, ep3)),
+ (iface2_nr),
+ (iface3_nr, (ep4))
+ * )
+ * @endcode
+ *
+ * @param type_name The name of the instance without _t postfix.
+ * @param interfaces_configs List of interface configurations like explained above.
+ * @param class_config_dec Result of the macro
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+ *
+ * @return The definition of the structure type that holds all the required data.
+ *
+ * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead.
+ *
+ * @note APP_USBD_CLASS_DATA_TYPEDEF has to be called first for the compilation to success.
+ *
+ * @sa APP_USBD_CLASS_TYPEDEF
+ */
+#define APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interfaces_configs, class_config_dec) \
+ typedef union CONCAT_2(type_name, _u) \
+ { \
+ app_usbd_class_inst_t base; \
+ struct \
+ { \
+ APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \
+ app_usbd_class_methods_t const * p_class_methods; \
+ struct \
+ { \
+ uint8_t cnt; \
+ app_usbd_class_iface_conf_t \
+ config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \
+ app_usbd_class_ep_conf_t \
+ ep[APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(interfaces_configs)]; \
+ } iface; \
+ class_config_dec \
+ } specific; \
+ } APP_USBD_CLASS_INSTANCE_TYPE(type_name)
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_INSTANCE_TYPEDEF but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_INSTANCE_NO_EP_TYPEDEF(type_name, interfaces_configs, class_config_dec) \
+ typedef union CONCAT_2(type_name, _u) \
+ { \
+ app_usbd_class_inst_t base; \
+ struct \
+ { \
+ APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \
+ app_usbd_class_methods_t const * p_class_methods; \
+ struct \
+ { \
+ uint8_t cnt; \
+ app_usbd_class_iface_conf_t \
+ config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \
+ } iface; \
+ class_config_dec \
+ } specific; \
+ } APP_USBD_CLASS_INSTANCE_TYPE(type_name)
+
+/**
+ * @brief Writable data structure declaration
+ *
+ * The macro that declares a variable type that would be used to store given class writable data.
+ * Writable data contains base part of the type @ref app_usbd_class_data_t followed by
+ * class specific data.
+ *
+ * @param type_name The name of the type without _t postfix.
+ * @param class_data_dec Result of the macro
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
+ *
+ * @return The definition of the structure type that holds all the required writable data
+ *
+ * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead.
+ *
+ * @sa APP_USBD_CLASS_TYPEDEF
+ */
+#define APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec) \
+ typedef struct \
+ { \
+ app_usbd_class_data_t base; \
+ class_data_dec \
+ }APP_USBD_CLASS_DATA_TYPE(type_name)
+
+
+/**
+ * @brief Declare all data types required by the class instance
+ *
+ * Macro that declares data type first and then instance type.
+ *
+ * @param type_name The name of the type without _t postfix.
+ * @param interface_configs List of interface configurations like in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF.
+ * @param class_config_dec Result of the macro
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+ * @param class_data_dec Result of the macro
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
+ *
+ * @return Declaration of the data type for the instance and instance itself.
+ *
+ * @sa APP_USBD_CLASS_DATA_TYPEDEF
+ * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
+ */
+#define APP_USBD_CLASS_TYPEDEF(type_name, interface_configs, class_config_dec, class_data_dec) \
+ APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \
+ APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interface_configs, class_config_dec)
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_TYPEDEF but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_NO_EP_TYPEDEF(type_name, \
+ interface_configs, \
+ class_config_dec, \
+ class_data_dec) \
+ APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \
+ APP_USBD_CLASS_INSTANCE_NO_EP_TYPEDEF(type_name, interface_configs, class_config_dec)
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF
+ *
+ * @param type_name The name of the type without _t postfix.
+ * */
+#define APP_USBD_CLASS_FORWARD(type_name) union CONCAT_2(type_name, _u)
+
+/**
+ * @brief Generate the initialization data for
+ *
+ * Macro that generates the initialization data for instance.
+ *
+ * @param p_ram_data Pointer to writable instance data structure
+ * @param class_methods Class methods
+ * @param interfaces_configs Exactly the same interface config data that in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ * @param class_config_part Configuration part. The data should be inside brackets.
+ * Any data here would be removed from brackets and then put as an initialization
+ * data for class_part member of instance structure.
+ *
+ * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_INST_DEF instead.
+ */
+#define APP_USBD_CLASS_INSTANCE_INITVAL(p_ram_data, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ { \
+ .specific = { \
+ .p_data = p_ram_data, \
+ .p_class_methods = class_methods, \
+ .iface = { \
+ .cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \
+ .config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) }, \
+ .ep = { APP_USBD_CLASS_IFACES_EP_EXTRACT(interfaces_configs) } \
+ }, \
+ BRACKET_EXTRACT(class_config_part) \
+ } \
+ }
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_INSTANCE_INITVAL but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_INSTANCE_NO_EP_INITVAL(p_ram_data, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ { \
+ .specific = { \
+ .p_data = p_ram_data, \
+ .p_class_methods = class_methods, \
+ .iface = { \
+ .cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \
+ .config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) } \
+ }, \
+ BRACKET_EXTRACT(class_config_part) \
+ } \
+ }
+
+/**
+ * @brief Define the base class instance
+ *
+ * Macro that defines whole instance variable and fill it with initialization data.
+ *
+ * The tricky part is @c class_config_part.
+ * The configuration data here has to be placed inside brackets.
+ * Then any type of values can be used depending on the type used in @ref APP_USBD_CLASS_TYPEDEF.
+ * If instance does not has any specyfic data, use just empty bracket here.
+ * @code
+ * APP_USBD_CLASS_TYPEDEF(
+ * some_base_class,
+ * CLASS_BASE_CONFIGURATION,
+ * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ * APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
+ * );
+ * APP_USBD_CLASS_INST_DEF(
+ * some_base_class_inst,
+ * some_base_class,
+ * base_class_event_handler,
+ * CLASS_BASE_CONFIGURATION,
+ * () // Empty configuration
+ * );
+ * @endcode
+ *
+ * If the type of instance configuration is simple type, just provide initialization value:
+ * @code
+ * APP_USBD_CLASS_TYPEDEF(
+ * some_base_class,
+ * CLASS_BASE_CONFIGURATION,
+ * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ * APP_USBD_CLASS_DATA_SPECIFIC_DEC(uint8_t)
+ * );
+ * APP_USBD_CLASS_INST_DEF(
+ * some_base_class_inst,
+ * some_base_class,
+ * base_class_event_handler,
+ * CLASS_BASE_CONFIGURATION,
+ * (12) // Example values
+ * );
+ * @endcode
+ *
+ * If the type of instance configuration is structure, provide initialization value for the whole structure:
+ * @code
+ * typedef structure
+ * {
+ * uint32_t p1;
+ * uint8_t p2;
+ * }my_config_t;
+ *
+ * APP_USBD_CLASS_TYPEDEF(
+ * some_base_class,
+ * CLASS_BASE_CONFIGURATION,
+ * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ * APP_USBD_CLASS_DATA_SPECIFIC_DEC(my_config_t)
+ * );
+ * APP_USBD_CLASS_INST_DEF(
+ * some_base_class_inst,
+ * some_base_class,
+ * base_class_event_handler,
+ * CLASS_BASE_CONFIGURATION,
+ * ({12, 3}) // Example values
+ * );
+ * @endcode
+ *
+ * @param instance_name The name of created instance variable.
+ * It would be constant variable and its type would be app_usbd_class_inst_t.
+ * @param type_name The name of the variable type. It has to be the same type that was passed to
+ * @ref APP_USBD_CLASS_TYPEDEF
+ * @param class_methods Class unified interface.
+ * @param interfaces_configs The same configuration data that the one passed to @ref APP_USBD_CLASS_TYPEDEF
+ * @param class_config_part Configuration data to the type that was declared by class_data_dec when calling
+ * @ref APP_USBD_CLASS_TYPEDEF.
+ * Configuration data has to be provided in brackets.
+ * It would be extracted from brackets and placed in initialization part of configuration structure.
+ * See detailed description of this macro for more informations.
+ */
+#define APP_USBD_CLASS_INST_DEF(instance_name, \
+ type_name, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
+ static const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
+ APP_USBD_CLASS_INSTANCE_INITVAL( \
+ &CONCAT_2(instance_name, _data), \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part)
+
+
+/**
+ * @brief Define the base class instance in global scope
+ *
+ * This is the same macro like @ref APP_USBD_CLASS_INST_DEF but it creates the instance
+ * without static keyword.
+ *
+ * @param instance_name See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param type_name See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param class_methods See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param interfaces_configs See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param class_config_part See documentation for @ref APP_USBD_CLASS_INST_DEF
+ */
+#define APP_USBD_CLASS_INST_GLOBAL_DEF(instance_name, \
+ type_name, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
+ const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
+ APP_USBD_CLASS_INSTANCE_INITVAL( \
+ &CONCAT_2(instance_name, _data), \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part)
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_INST_GLOBAL_DEF but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF(instance_name, \
+ type_name, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
+ const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
+ APP_USBD_CLASS_INSTANCE_NO_EP_INITVAL( \
+ &CONCAT_2(instance_name, _data), \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part)
+/**
+ * @brief Access class specific configuration
+ *
+ * Macro that returns class specific configuration.
+ *
+ * @param[in] p_inst Instance pointer
+ *
+ * @return A pointer for class specific part of the instance
+ *
+ * @note If macro is used on the instance that has no class specific configuration
+ * an error would be generated during compilation.
+ */
+#define APP_USBD_CLASS_GET_SPECIFIC_CONFIG(p_inst) (&((p_inst)->specific.class_part))
+
+/**
+ * @brief Access class specific data
+ *
+ * @param[in] p_inst Instance pointer
+ *
+ * @return A pointer for class specific part of writable data
+ *
+ * @note If macro is used on the instance that has no class specific data
+ * an error would be generated during compilation.
+ */
+#define APP_USBD_CLASS_GET_SPECIFIC_DATA(p_inst) (&(((p_inst)->specific.p_data)->class_part))
+
+/**
+ * @brief Macro to get base instance from class specific instance
+ *
+ * This macro may be used on class specific instance to get base instance that
+ * can be processed by base instance access functions.
+ * Class specific instance can be just casted to class base instance,
+ * but then we would totally lost type safety.
+ *
+ * A little more safe is to use pointer to base member of class instance.
+ * This would generate an error when used on any variable that has no base member
+ * and would generate also error if this base member is wrong type.
+ */
+#define APP_USBD_CLASS_BASE_INSTANCE(p_inst) (&((p_inst)->base))
+
+/*lint -emacro(142 438 616 646, APP_USBD_CLASS_DESCRIPTOR_INIT, APP_USBD_CLASS_DESCRIPTOR_BEGIN, APP_USBD_CLASS_DESCRIPTOR_YIELD, APP_USBD_CLASS_DESCRIPTOR_END, APP_USBD_CLASS_DESCRIPTOR_WRITE)*/
+
+/**
+ * @brief Initialize class descriptor
+ *
+ * @param[in] p_ctx Class descriptor context
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_INIT(p_ctx) \
+ (p_ctx)->line = 0;
+
+/**
+ * @brief Begin class descriptor
+ *
+ * @param[in] p_ctx Class descriptor context
+ * @param[in] p_buff Buffer to write into
+ * @param[in] max_size Size of the buffer
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size) \
+ ASSERT((p_ctx) != NULL); \
+ app_usbd_class_descriptor_state_t this_descriptor_feed; \
+ this_descriptor_feed.p_buffer = (p_buff); \
+ this_descriptor_feed.current_size = 0; \
+ this_descriptor_feed.maximum_size = (max_size); \
+ this_descriptor_feed.p_context = (p_ctx); \
+ switch ((this_descriptor_feed.p_context)->line) \
+ { \
+ case 0: \
+ ;
+
+/**
+ * @brief Yield class descriptor
+ *
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_YIELD() \
+do \
+{ \
+ (this_descriptor_feed.p_context)->line = __LINE__; \
+ return true; \
+ case __LINE__: \
+ ; \
+} while (0)
+
+/*lint -emacro(438 527, APP_USBD_CLASS_DESCRIPTOR_END)*/
+
+/**
+ * @brief End class descriptor
+ *
+ * This function has to be called at the end of class descriptor feeder function.
+ * No other operations in feeder function can be done after calling it.
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_END() \
+ APP_USBD_CLASS_DESCRIPTOR_YIELD(); \
+ } \
+ (this_descriptor_feed.p_context)->line = 0; \
+ return false;
+
+
+/**
+ * @brief Write descriptor using protothreads
+ *
+ * This function writes one byte to the buffer with offset. If buffer is full
+ * it yields.
+ *
+ * It is used by the class descriptor feeders internally.
+ *
+ * @ref APP_USBD_CLASS_DESCRIPTOR_BEGIN has to be called before using this function.
+ * @ref APP_USBD_CLASS_DESCRIPTOR_END has to be called after last use of this function.
+ *
+ * @param data Byte to be written to buffer
+ */
+#define APP_USBD_CLASS_DESCRIPTOR_WRITE(data) \
+do \
+{ \
+ (this_descriptor_feed.p_context)->data_buffer = (data); \
+ if (this_descriptor_feed.current_size >= this_descriptor_feed.maximum_size) \
+ { \
+ APP_USBD_CLASS_DESCRIPTOR_YIELD(); \
+ } \
+ if(this_descriptor_feed.p_buffer != NULL) \
+ { \
+ *(this_descriptor_feed.p_buffer + this_descriptor_feed.current_size) = \
+ (this_descriptor_feed.p_context)->data_buffer; \
+ } \
+ this_descriptor_feed.current_size++; \
+} while(0);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CLASS_BASE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c
new file mode 100644
index 0000000..c2b02ce
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c
@@ -0,0 +1,1222 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD)
+
+#include "app_usbd_core.h"
+#include "app_usbd.h"
+#include "app_usbd_request.h"
+#include "app_usbd_string_desc.h"
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "app_util_platform.h"
+#include "app_usbd.h"
+#include "app_usbd_class_base.h"
+
+#define NRF_LOG_MODULE_NAME app_usbd_core
+
+#if APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/* Test if VID was configured */
+#ifndef APP_USBD_VID
+#error APP_USBD_VID not properly defined.
+#endif
+
+
+/* Device version checking */
+#if defined(APP_USBD_DEVICE_VER_MAJOR) && defined(APP_USBD_DEVICE_VER_MINOR)
+ #if ((APP_USBD_DEVICE_VER_MAJOR)) > 99 || ((APP_USBD_DEVICE_VER_MINOR) > 99)
+ #error Major and minor device version value have to be limited to 99.
+ #endif
+#else
+ #error The definition of a pair APP_USBD_DEVICE_VER_MAJOR and APP_USBD_DEVICE_VER_MINOR required.
+#endif
+
+/**
+ * @internal
+ * @defgroup app_usbd_core_internals USB Device high level library core module internals
+ * @ingroup app_usbd_core
+ *
+ * Internal variables, auxiliary macros and functions of USBD high level core module.
+ * @{
+ */
+
+/** @brief Make USB power value */
+#define APP_USBD_POWER_MAKE(ma) (((ma) + 1) / 2)
+
+/**
+ @brief Default device descriptor initializer @ref app_usbd_descriptor_device_t
+* */
+#define APP_USBD_CORE_DEVICE_DESCRIPTOR { \
+ .bLength = sizeof(app_usbd_descriptor_device_t), /* descriptor size */ \
+ .bDescriptorType = APP_USBD_DESCRIPTOR_DEVICE, /* descriptor type */ \
+ .bcdUSB = APP_USBD_BCD_VER_MAKE(2,0), /* USB BCD version: 2.0 */ \
+ .bDeviceClass = 0, /* device class: 0 - specified by interface */ \
+ .bDeviceSubClass = 0, /* device subclass: 0 - specified by interface */ \
+ .bDeviceProtocol = 0, /* device protocol: 0 - specified by interface */ \
+ .bMaxPacketSize0 = NRF_DRV_USBD_EPSIZE, /* endpoint size: fixed to: NRF_DRV_USBD_EPSIZE*/ \
+ .idVendor = APP_USBD_VID, /* Vendor ID*/ \
+ .idProduct = APP_USBD_PID, /* Product ID*/ \
+ .bcdDevice = APP_USBD_BCD_VER_MAKE( /* Device version BCD */ \
+ APP_USBD_DEVICE_VER_MAJOR, \
+ APP_USBD_DEVICE_VER_MINOR), \
+ .iManufacturer = APP_USBD_STRING_ID_MANUFACTURER, /* String ID: manufacturer */ \
+ .iProduct = APP_USBD_STRING_ID_PRODUCT, /* String ID: product */ \
+ .iSerialNumber = APP_USBD_STRING_ID_SERIAL, /* String ID: serial */ \
+ .bNumConfigurations = 1 /* Fixed value: only one configuration supported*/\
+}
+
+
+#define APP_USBD_CORE_CONFIGURATION_DESCRIPTOR { \
+ .bLength = sizeof(app_usbd_descriptor_configuration_t), \
+ .bDescriptorType = APP_USBD_DESCRIPTOR_CONFIGURATION, \
+ .wTotalLength = 0, /*Calculated dynamically*/ \
+ .bNumInterfaces = 0, /*Calculated dynamically*/ \
+ .bConfigurationValue = 1, /*Value passed to set configuration*/ \
+ .iConfiguration = 0, /*Configuration ID: fixed to 0*/ \
+ .bmAttributes = APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK | \
+ ((APP_USBD_CONFIG_SELF_POWERED) ? \
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK \
+ : \
+ 0), \
+ .bMaxPower = APP_USBD_POWER_MAKE(APP_USBD_CONFIG_MAX_POWER), \
+}
+
+/**
+ * @brief Device descriptor instance.
+ *
+ * @note
+ * Constant part of the device descriptor.
+ * Values that must be calculated are updated directly in the buffer
+ * just before the transmission.
+ */
+static const app_usbd_descriptor_device_t m_device_dsc =
+ APP_USBD_CORE_DEVICE_DESCRIPTOR;
+
+/**
+ * @brief Configuration descriptor instance.
+ *
+ * @note
+ * Constant part of the device descriptor.
+ * Values that must be calculated are updated directly in the buffer
+ * just before the transmission.
+ */
+static const app_usbd_descriptor_configuration_t m_configuration_dsc =
+ APP_USBD_CORE_CONFIGURATION_DESCRIPTOR;
+
+/* Required early declaration of event handler function */
+static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event);
+
+/**
+ * @brief Current USB device state
+ *
+ * This variable is updated automatically by core library.
+ */
+static app_usbd_state_t m_app_usbd_state = APP_USBD_STATE_Disabled;
+
+/**
+ * @brief Active device features
+ *
+ * @note Only @ref APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP is supported for device
+ */
+static uint8_t m_device_features_state;
+
+/**
+ * @brief Remote wake-up pending flag
+ */
+static nrf_atomic_flag_t m_rwu_pending;
+
+
+/**
+ * @brief Core class methods
+ *
+ * Base methods interface for core class.
+ * This is quite specific class - it would be only connected into endpoint 0.
+ * Not connected into instances list.
+ */
+static const app_usbd_class_methods_t m_core_methods = {
+ .event_handler = app_usbd_core_event_handler,
+ .feed_descriptors = NULL,
+};
+
+/**
+ * @brief Setup transfer buffer
+ */
+static uint8_t m_setup_transfer_buff[NRF_DRV_USBD_EPSIZE];
+
+
+/**
+ * @brief Handler for outgoing setup data
+ *
+ * @todo RK documentation
+ */
+static app_usbd_core_setup_data_handler_desc_t m_ep0_handler_desc;
+
+#define APP_USBD_CORE_CLASS_INSTANCE_CONFIG ()
+
+
+/*lint -u -save -e26 -e40 -e64 -e123 -e505 -e651*/
+
+/**
+ * @brief Core instance
+ *
+ * Create instance that would be connected into endpoints in USBD library.
+ */
+APP_USBD_CLASS_INST_GLOBAL_DEF(
+ app_usbd_core_inst,
+ app_usbd_core,
+ &m_core_methods,
+ APP_USBD_CORE_CLASS_CONFIGURATION,
+ () );
+/*lint -restore*/
+
+/**
+ * @brief Set the new USB state
+ *
+ * Function changes the internal status of the bus.
+ * If the bus status is different than the one configured, an event is passed to all
+ * the instances.
+ *
+ * @param state New state to be set
+ *
+ * @sa usbd_core_state_get
+ */
+static void usbd_core_state_set(app_usbd_state_t state)
+{
+ if (m_app_usbd_state != state)
+ {
+ m_app_usbd_state = state;
+ if(state != APP_USBD_STATE_Configured)
+ {
+ CLR_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP);
+ }
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STATE_CHANGED
+ };
+ app_usbd_event_execute((app_usbd_internal_evt_t const *)&evt_data);
+ }
+}
+
+/**
+ * @brief Get the current USB state - internal function
+ *
+ * This is just a wrapper for @ref app_usbd_core_state_get
+ * to make symmetrical function to the internal @ref usbd_core_state_set.
+ *
+ * @return Current USB state
+ *
+ * @sa usbd_core_state_set
+ * @sa app_usbd_core_state_get
+ */
+static inline app_usbd_state_t usbd_core_state_get(void)
+{
+ return m_app_usbd_state;
+}
+
+/**
+ * @brief Check current USBD power connection status
+ *
+ */
+static inline bool usbd_core_power_is_detected(void)
+{
+ return 0 != ( (NRF_POWER->USBREGSTATUS) & POWER_USBREGSTATUS_VBUSDETECT_Msk);
+}
+
+/**
+ * @brief Clear current EP0 handler
+ *
+ * Function just clears the EP0 handler without calling it
+ */
+static inline void usbd_core_ep0_handler_clear(void)
+{
+ m_ep0_handler_desc.handler = NULL;
+}
+
+/**
+ * @brief Safely call EP0 handler
+ *
+ * Function calls EP0 handler only if its pointer is non-zero.
+ *
+ * @param status Status to send as a handler parameter.
+ */
+static inline ret_code_t usbd_core_ep0_handler_call_and_clear(nrf_drv_usbd_ep_status_t status)
+{
+ app_usbd_core_setup_data_handler_t handler = m_ep0_handler_desc.handler;
+ if (NULL != handler)
+ {
+ usbd_core_ep0_handler_clear();
+ return handler(status, m_ep0_handler_desc.p_context);
+ }
+
+ return NRF_ERROR_NULL;
+}
+
+/**
+ * @brief Check if EP0 handler is configured
+ *
+ * EP0 handler is configured is any instance that has processed SETUP command
+ * expects some incoming / outgoing data.
+ *
+ * EP0 handler should be cleared automatically just before it is called
+ * (see @ref usbd_core_ep0_handler_call_and_clear).
+ * If instance requires more data - it has to setup EP0 handler once more time
+ * (see @ref app_usbd_core_setup_data_handler_set).
+ *
+ * This function adds small layer of abstraction for checking if EP0 handler
+ * is already configured.
+ *
+ * @retval true EP0 handler is set
+ * @retval false EP0 handler is cleared
+ */
+static inline bool usb_core_ep0_handler_check(void)
+{
+ return (NULL != m_ep0_handler_desc.handler);
+}
+
+/**
+ * @brief Empty data handler
+ *
+ * Data handler used only to mark that there is requested data during SETUP.
+ *
+ * @return Always NRF_SUCCESS
+ * @sa setup_empty_data_handler_desc
+ */
+static ret_code_t setup_data_handler_empty(nrf_drv_usbd_ep_status_t status, void * p_contex)
+{
+ UNUSED_PARAMETER(status);
+ UNUSED_PARAMETER(p_contex);
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief
+ *
+ * @todo RK Documentation
+ */
+static app_usbd_core_setup_data_handler_desc_t const m_setup_data_handler_empty_desc =
+{
+ .handler = setup_data_handler_empty,
+ .p_context = NULL
+};
+
+/**
+ * @brief Structure used as a context for descriptor feeder
+ *
+ * Structure with all the data required to process instances to generate descriptor
+ * data chunk.
+ */
+typedef struct
+{
+ app_usbd_class_inst_t const * p_cinst; //!< The class instance that is to be processed next.
+ const uint8_t * p_desc; //!< Pointer at current descriptor or NULL if finished.
+ /**<
+ * If the value passed by @ref p_desc is NULL on transfer function enter it means that ZLP is required.
+ * Or it is time to finish the transfer (depending on @c total_left).
+ */
+ size_t desc_left; //!< Number of bytes left in the current class descriptor to send
+ size_t total_left; //!< Number of bytes left that was requested by the host
+ app_usbd_class_descriptor_ctx_t feed_thread; //!< Class descriptor context
+} app_usbd_core_descriptor_conf_feed_data_t;
+
+/**
+ * @brief Default data used by the feeder
+ *
+ *
+ */
+static app_usbd_core_descriptor_conf_feed_data_t m_descriptor_conf_feed_data;
+
+/**
+ * @brief Descriptor feeder
+ *
+ * Descriptor feeder is used as an callback function when descriptors are
+ * transfered and buffer is ready for next data.
+ * It prepares next chunk of data to be sent.
+ *
+ * @param p_next See @ref nrf_drv_usbd_next_transfer_handler_t documentation.
+ * @param p_context Pointer to @ref app_usbd_core_descriptor_feed_data_t data type.
+ * @param ep_size The size of the endpoint.
+ *
+ * @return See @ref nrf_drv_usbd_next_transfer_handler_t documentation.
+ */
+static bool usbd_descriptor_conf_feeder(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size)
+{
+ bool continue_req = true;
+
+ app_usbd_core_descriptor_conf_feed_data_t * p_data = p_context;
+
+
+ if ((p_data->p_desc == NULL) && (app_usbd_class_next_get(p_data->p_cinst) == NULL)
+ && (p_data->desc_left == 0))
+ {
+ /* ZLP */
+ continue_req = false;
+ p_next->p_data.tx = NULL;
+ p_next->size = 0;
+ }
+ else
+ {
+ ASSERT(ep_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE);
+ uint8_t * p_tx_buff;
+ size_t size = 0; /* Currently added number of bytes */
+ size_t tx_size; /* Number of bytes to send right now */
+ bool feeding = false;
+
+ /* Feeder function can use the USBD driver internal buffer */
+ p_tx_buff = nrf_drv_usbd_feeder_buffer_get();
+
+ tx_size = MIN(ep_size, p_data->total_left);
+
+ while (0 != tx_size)
+ {
+ size_t to_copy = MIN(tx_size, p_data->desc_left);
+
+ /* First transfer */
+ if (p_data->p_desc != NULL)
+ {
+ memcpy(p_tx_buff + size, p_data->p_desc, to_copy);
+ p_data->p_desc = NULL;
+ }
+ /* Starting with second transfer */
+ else if (0 < p_data->desc_left)
+ {
+ UNUSED_RETURN_VALUE(p_data->p_cinst->p_class_methods->feed_descriptors(
+ &p_data->feed_thread, p_data->p_cinst,
+ (uint8_t *)p_tx_buff + size, to_copy));
+ feeding = true;
+ }
+ else
+ {
+ ;
+ }
+
+ p_data->desc_left -= to_copy;
+ p_data->total_left -= to_copy;
+ tx_size -= to_copy;
+ size += to_copy;
+
+ /* Switch to next class if no descriptor left and first feeding was done */
+ if(p_data->desc_left == 0 && feeding)
+ {
+ p_data->p_cinst = app_usbd_class_next_get(p_data->p_cinst);
+ }
+
+ if (0 == p_data->total_left)
+ {
+ continue_req = false;
+ }
+ else if (0 == p_data->desc_left)
+ {
+ if (NULL == p_data->p_cinst)
+ {
+ p_data->p_desc = NULL;
+ /* No more data - check if ZLP is required */
+ if (size > 0)
+ {
+ if (size < ep_size)
+ {
+ continue_req = false;
+ }
+ }
+ break;
+ }
+ else
+ {
+ /* New class - count descriptor size and initialize feeding thread */
+ app_usbd_class_descriptor_ctx_t desiz;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&desiz);
+ while(p_data->p_cinst->p_class_methods->feed_descriptors(
+ &desiz, p_data->p_cinst, NULL, sizeof(uint8_t)))
+ {
+ p_data->desc_left++;
+ }
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&p_data->feed_thread);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ p_next->p_data.tx = p_tx_buff;
+ p_next->size = size;
+ }
+ return continue_req;
+}
+
+/**
+ * @brief Standard endpoint request handle
+ *
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ */
+static ret_code_t setup_endpoint_req_std(app_usbd_setup_evt_t const * p_setup_ev)
+{
+ if (APP_USBD_SETUP_REQTYPE_STD != app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ nrf_drv_usbd_ep_t ep_addr = (nrf_drv_usbd_ep_t)(p_setup_ev->setup.wIndex.lb);
+ app_usbd_state_t usb_state = usbd_core_state_get();
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_GET_STATUS:
+ {
+ if ((usb_state == APP_USBD_STATE_Configured) || (NRF_USBD_EP_NR_GET(ep_addr) == 0))
+ {
+ size_t tx_size;
+ uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+
+ p_tx_buff[0] = nrf_drv_usbd_ep_stall_check(ep_addr) ? 1 : 0;
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t));
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ case APP_USBD_SETUP_STDREQ_SET_FEATURE:
+ {
+ if ((!NRF_USBD_EPISO_CHECK(ep_addr)) &&
+ (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT))
+ {
+ if ((usb_state == APP_USBD_STATE_Configured) || (NRF_USBD_EP_NR_GET(ep_addr) == 0))
+ {
+ nrf_drv_usbd_ep_stall(ep_addr);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ break;
+ }
+ case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE:
+ {
+ if ((!NRF_USBD_EPISO_CHECK(ep_addr)) &&
+ (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT))
+ {
+ if ((usb_state == APP_USBD_STATE_Configured) || (NRF_USBD_EP_NR_GET(ep_addr) == 0))
+ {
+ nrf_drv_usbd_ep_dtoggle_clear(ep_addr);
+ nrf_drv_usbd_ep_stall_clear(ep_addr);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Standard interface request handle
+ *
+ * @param[in,out] p_class_inst Class instance that holds selected interface
+ * @param[in] iface_idx Index of the interface in class structure
+ * @param[in] p_event Event structure to be processed
+ *
+ * @return Operation status
+ */
+static ret_code_t setup_interface_req_std_handle(
+ app_usbd_class_inst_t const * const p_class_inst,
+ uint8_t iface_idx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ if (APP_USBD_SETUP_REQTYPE_STD != app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ app_usbd_state_t usb_state = usbd_core_state_get();
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_GET_STATUS:
+ {
+ if (!(usb_state == APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ size_t tx_size;
+ uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+ p_tx_buff[0] = 0;
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t));
+ }
+ case APP_USBD_SETUP_STDREQ_GET_INTERFACE:
+ {
+ if (!(usb_state == APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ size_t tx_size;
+ uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+ p_tx_buff[0] = app_usbd_iface_selection_get(p_class_inst, iface_idx);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint8_t));
+ }
+ }
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_SET_INTERFACE:
+ {
+ if (!(usb_state == APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if(p_setup_ev->setup.wValue.w > UINT8_MAX)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t alt = p_setup_ev->setup.wValue.lb;
+ return app_usbd_iface_select(p_class_inst, iface_idx, alt);
+ }
+ default:
+ break;
+ }
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief
+ *
+ * @todo RK Documentation
+ */
+static const nrf_drv_usbd_handler_desc_t usbd_descriptor_feeder_desc =
+{
+ .handler = { .feeder = usbd_descriptor_conf_feeder },
+ .p_context = &m_descriptor_conf_feed_data
+};
+
+static ret_code_t setup_device_req_get_status(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ size_t max_size;
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+ ASSERT(sizeof(uint16_t) <= max_size);
+
+ memset(p_trans_buff, 0, sizeof(uint16_t));
+ if (m_configuration_dsc.bmAttributes &
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK)
+ {
+ SET_BIT(p_trans_buff[0], 0);
+ }
+ if (IS_SET(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP))
+ {
+ SET_BIT(p_trans_buff[0], 1);
+ }
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, sizeof(uint16_t));
+}
+
+static ret_code_t setup_device_req_get_descriptor(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ switch (p_setup_ev->setup.wValue.hb)
+ {
+ case APP_USBD_DESCRIPTOR_DEVICE:
+ {
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup),
+ &m_device_dsc,
+ sizeof(m_device_dsc));
+ }
+ case APP_USBD_DESCRIPTOR_CONFIGURATION:
+ {
+ /* The size equals the size of configuration descriptor and all classes descriptors */
+ const size_t size = MIN(
+ sizeof(app_usbd_descriptor_configuration_t),
+ p_setup_ev->setup.wLength.w);
+ size_t total_length = sizeof(app_usbd_descriptor_configuration_t);
+ uint8_t iface_count = 0;
+
+ /* Iterate over all registered classes count descriptors and total size */
+ app_usbd_class_inst_t const * p_class;
+ for (p_class = app_usbd_class_first_get(); p_class != NULL;
+ p_class = app_usbd_class_next_get(p_class))
+ {
+ ASSERT(NULL != (p_class->p_class_methods));
+ ASSERT(NULL != (p_class->p_class_methods->feed_descriptors));
+ size_t dsc_size = 0;
+ app_usbd_class_descriptor_ctx_t siz_desc;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&siz_desc);
+ while(p_class->p_class_methods->feed_descriptors(&siz_desc,
+ p_class,
+ NULL,
+ sizeof(uint8_t))
+ )
+ {
+ dsc_size++;
+ }
+ total_length += dsc_size;
+ iface_count += app_usbd_class_iface_count_get(p_class);
+ }
+
+ /* Access transmission buffer */
+ size_t max_size;
+ app_usbd_descriptor_configuration_t * p_trans_buff =
+ app_usbd_core_setup_transfer_buff_get(&max_size);
+ /* Copy the configuration descriptor and update the fields that require it */
+ ASSERT(size <= max_size);
+ memcpy(p_trans_buff, &m_configuration_dsc, size);
+
+ p_trans_buff->bNumInterfaces = iface_count;
+ p_trans_buff->wTotalLength = total_length;
+ if (app_usbd_class_rwu_enabled_check())
+ {
+ p_trans_buff->bmAttributes |=
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK;
+ }
+
+
+ m_descriptor_conf_feed_data.p_cinst = app_usbd_class_first_get();
+ m_descriptor_conf_feed_data.p_desc = (void *)p_trans_buff;
+ m_descriptor_conf_feed_data.desc_left = size;
+ m_descriptor_conf_feed_data.total_left = p_setup_ev->setup.wLength.w;
+
+ /* Start first transfer */
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+
+ ret = app_usbd_ep_handled_transfer(
+ NRF_DRV_USBD_EPIN0,
+ &usbd_descriptor_feeder_desc);
+
+ if (NRF_SUCCESS == ret)
+ {
+ ret = app_usbd_core_setup_data_handler_set(
+ NRF_DRV_USBD_EPIN0,
+ &m_setup_data_handler_empty_desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+ }
+ case APP_USBD_DESCRIPTOR_STRING:
+ {
+ app_usbd_string_desc_idx_t id =
+ (app_usbd_string_desc_idx_t)(p_setup_ev->setup.wValue.lb);
+ uint16_t langid = p_setup_ev->setup.wIndex.w;
+ uint16_t const * p_string_dsc = app_usbd_string_desc_get(id, langid);
+ if (p_string_dsc == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(
+ &p_setup_ev->setup,
+ p_string_dsc,
+ app_usbd_string_desc_length(p_string_dsc));
+ }
+ default:
+ break;
+ }
+
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static ret_code_t setup_device_req_get_configuration(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ size_t max_size;
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+ app_usbd_state_t usb_state = usbd_core_state_get();
+ if (usb_state == APP_USBD_STATE_Configured)
+ {
+ p_trans_buff[0] = 1;
+ }
+ else if (usb_state == APP_USBD_STATE_Addressed)
+ {
+ p_trans_buff[0] = 0;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup, p_trans_buff, sizeof(p_trans_buff[0]));
+}
+
+static ret_code_t setup_device_req_set_configuration(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ app_usbd_state_t usb_state = usbd_core_state_get();
+ if (!((usb_state == APP_USBD_STATE_Configured) ||
+ (usb_state == APP_USBD_STATE_Addressed)))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (p_setup_ev->setup.wValue.lb == 0)
+ {
+ app_usbd_all_iface_deselect();
+ usbd_core_state_set(APP_USBD_STATE_Addressed);
+ }
+ else if (p_setup_ev->setup.wValue.lb == 1)
+ {
+ /*Clear all bulk/interrupt endpoint status and set toggle to DATA0*/
+ app_usbd_all_iface_select_0();
+ usbd_core_state_set(APP_USBD_STATE_Configured);
+ }
+ else
+ {
+ /*In this driver only one configuration is supported.*/
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Internal SETUP event handler
+ * @param[in] p_inst Instance of the class
+ * @param[in] p_setup_ev Setup request
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_device_req_std_handler(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (APP_USBD_SETUP_REQTYPE_STD != app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_GET_STATUS:
+ {
+ return setup_device_req_get_status(p_inst, p_setup_ev);
+ }
+ case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR:
+ {
+ return setup_device_req_get_descriptor(p_inst, p_setup_ev);
+ }
+ case APP_USBD_SETUP_STDREQ_GET_CONFIGURATION:
+ {
+ return setup_device_req_get_configuration(p_inst, p_setup_ev);
+ }
+ default:
+ /*Not supported*/
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_SET_ADDRESS:
+ {
+ app_usbd_state_t usb_state = usbd_core_state_get();
+ if ((usb_state != APP_USBD_STATE_Default) &&
+ (usb_state != APP_USBD_STATE_Addressed) &&
+ (usb_state != APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ app_usbd_all_iface_deselect();
+ usbd_core_state_set(APP_USBD_STATE_Addressed);
+ return NRF_SUCCESS;
+ }
+ case APP_USBD_SETUP_STDREQ_SET_FEATURE:
+ {
+ if (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP)
+ {
+ if (!app_usbd_class_rwu_enabled_check())
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ SET_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP);
+ return NRF_SUCCESS;
+ }
+ break;
+ }
+ case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE:
+ {
+ if (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP)
+ {
+ if (!app_usbd_class_rwu_enabled_check())
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ CLR_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP);
+ return NRF_SUCCESS;
+ }
+ break;
+ }
+ case APP_USBD_SETUP_STDREQ_SET_CONFIGURATION:
+ {
+ return setup_device_req_set_configuration(p_inst, p_setup_ev);
+ }
+ case APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR:
+ {
+ /*Not supported yet.*/
+ break;
+ }
+ default:
+ /*Not supported*/
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+}
+
+/**
+ * @brief Process SETUP command
+ *
+ * Auxiliary function for SETUP command processing
+ */
+static inline ret_code_t app_usbd_core_setup_req_handler(app_usbd_class_inst_t const * const p_inst)
+{
+ app_usbd_setup_evt_t setup_ev;
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED; /* Final result of request processing function */
+
+ setup_ev.type = APP_USBD_EVT_DRV_SETUP;
+ nrf_drv_usbd_setup_get((nrf_drv_usbd_setup_t *)&(setup_ev.setup));
+
+ NRF_LOG_DEBUG("SETUP: t: 0x%.2x r: 0x%.2x",
+ setup_ev.setup.bmRequestType,
+ setup_ev.setup.bmRequest);
+ if (usb_core_ep0_handler_check())
+ {
+ NRF_LOG_WARNING("Previous setup not finished!");
+ }
+ /* Clear EP0 handler if there is anything in progress */
+ usbd_core_ep0_handler_clear();
+
+ switch (app_usbd_setup_req_rec(setup_ev.setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQREC_DEVICE:
+ {
+ /* Endpoint 0 has core instance (that process device requests) connected */
+ ret = setup_device_req_std_handler(p_inst, &setup_ev);
+ if (ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t const *)&setup_ev);
+ }
+ break;
+ }
+ case APP_USBD_SETUP_REQREC_INTERFACE:
+ {
+ uint8_t const iface_number = setup_ev.setup.wIndex.lb;
+ uint8_t iface_idx;
+ app_usbd_class_inst_t const * p_inst_found = app_usbd_iface_find(
+ iface_number,
+ &iface_idx);
+ if (p_inst_found == NULL)
+ {
+ ret = NRF_ERROR_INVALID_ADDR;
+ }
+ else
+ {
+ ret = app_usbd_iface_call(
+ p_inst_found, iface_idx,
+ (app_usbd_complex_evt_t const *)&setup_ev);
+ if (ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = setup_interface_req_std_handle(p_inst_found, iface_idx, &setup_ev);
+ }
+ }
+ break;
+ }
+ case APP_USBD_SETUP_REQREC_ENDPOINT:
+ {
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ nrf_drv_usbd_ep_t ep = (nrf_drv_usbd_ep_t)setup_ev.setup.wIndex.lb;
+ if ((NRF_USBD_EP_NR_GET(ep) != 0)) /* For EP0 we would call this function again! */
+ {
+ ret = app_usbd_ep_call(ep, (app_usbd_complex_evt_t const *)&setup_ev);
+ }
+ if (ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = setup_endpoint_req_std(&setup_ev);
+ }
+ break;
+ }
+ case APP_USBD_SETUP_REQREC_OTHER:
+ {
+ /* Try to process via every instance */
+ ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t const *)&setup_ev);
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Processing result */
+ if (ret == NRF_SUCCESS)
+ {
+ if (usb_core_ep0_handler_check())
+ {
+ if (NRF_DRV_USBD_EPOUT0 == nrf_drv_usbd_last_setup_dir_get())
+ {
+ /* Request processed successfully and requires SETUP data */
+ nrf_drv_usbd_setup_data_clear();
+ }
+ }
+ else
+ {
+ /* Request processed successfully */
+ nrf_drv_usbd_setup_clear();
+ }
+ }
+ else
+ {
+ /* Request finished with error */
+ nrf_drv_usbd_setup_stall();
+ }
+ return ret;
+}
+
+/**
+ * @brief Event handler for core module
+ *
+ * The event handler that would process all events directed to device.
+ *
+ */
+static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event)
+{
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
+ switch (p_event->type)
+ {
+ case APP_USBD_EVT_DRV_RESET:
+ {
+ usbd_core_state_set(APP_USBD_STATE_Default);
+ break;
+ }
+ case APP_USBD_EVT_DRV_SUSPEND:
+ {
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_DRV_RESUME:
+ {
+ if (nrf_atomic_flag_clear_fetch(&m_rwu_pending) != 0)
+ {
+ nrf_usbd_task_trigger(NRF_USBD_TASK_NODRIVEDPDM);
+ }
+
+ ASSERT(usbd_core_state_get() >= APP_USBD_STATE_Unattached);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_DRV_SETUP:
+ {
+ ret = app_usbd_core_setup_req_handler(p_inst);
+ break;
+ }
+ case APP_USBD_EVT_INST_APPEND:
+ {
+ ASSERT(usbd_core_state_get() == APP_USBD_STATE_Disabled);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_INST_REMOVE:
+ {
+ ASSERT(usbd_core_state_get() == APP_USBD_STATE_Unattached);
+ usbd_core_state_set(APP_USBD_STATE_Disabled);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_STARTED:
+ {
+ if (usbd_core_power_is_detected())
+ {
+ usbd_core_state_set(APP_USBD_STATE_Powered);
+ }
+ else
+ {
+ usbd_core_state_set(APP_USBD_STATE_Unattached);
+ }
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_STOPPED:
+ {
+ ASSERT(usbd_core_state_get() >= APP_USBD_STATE_Powered);
+ usbd_core_state_set(APP_USBD_STATE_Unattached);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ /* Data transfer on endpoint 0 */
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ {
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_ABORTED)
+ {
+ /* Just ignore aborting */
+ break;
+ }
+ /* This EPTRANSFER event has to be called only for EP0 */
+ ASSERT((p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0) ||
+ (p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPIN0));
+ ret = usbd_core_ep0_handler_call_and_clear(p_event->drv_evt.data.eptransfer.status);
+ /* Processing result */
+ if (ret == NRF_SUCCESS)
+ {
+ if (usb_core_ep0_handler_check())
+ {
+ if (p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0)
+ {
+ /* Request processed successfully and requires SETUP data */
+ nrf_drv_usbd_setup_data_clear();
+ }
+ }
+ else
+ {
+ if (!nrf_drv_usbd_errata_154())
+ {
+ nrf_drv_usbd_setup_clear();
+ }
+ }
+ }
+ else
+ {
+ /* Request finished with error */
+ nrf_drv_usbd_setup_stall();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/** @} */
+
+ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup,
+ void const * p_data,
+ size_t size)
+{
+ size_t req_size = p_setup->wLength.w;
+ size_t tx_size = MIN(req_size, size);
+ bool zlp_required = (size < req_size) &&
+ (0 == (size % nrf_drv_usbd_ep_max_packet_size_get(NRF_DRV_USBD_EPIN0)));
+
+ NRF_DRV_USBD_TRANSFER_IN_FLAGS(
+ transfer,
+ p_data,
+ tx_size,
+ zlp_required ? NRF_DRV_USBD_TRANSFER_ZLP_FLAG : 0);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, &transfer);
+ if (NRF_SUCCESS == ret)
+ {
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPIN0,
+ &m_setup_data_handler_empty_desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+ret_code_t app_usbd_core_setup_data_handler_set(
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc)
+{
+ if (nrf_drv_usbd_last_setup_dir_get() != ep)
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ m_ep0_handler_desc = *p_handler_desc;
+ return NRF_SUCCESS;
+}
+
+void * app_usbd_core_setup_transfer_buff_get(size_t * p_size)
+{
+ if (p_size != NULL)
+ *p_size = sizeof(m_setup_transfer_buff);
+
+ return m_setup_transfer_buff;
+}
+
+app_usbd_state_t app_usbd_core_state_get(void)
+{
+ return usbd_core_state_get();
+}
+
+
+bool app_usbd_core_feature_state_get(app_usbd_setup_stdfeature_t feature)
+{
+ return IS_SET(m_device_features_state, feature) ? true : false;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h
new file mode 100644
index 0000000..7c6c12e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_CORE_H__
+#define APP_USBD_CORE_H__
+
+#include <stdint.h>
+
+#include "sdk_common.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_types.h"
+#include "app_usbd_class_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_core USB Device high level library core module
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Core module that manages current USB state and process device requests.
+ * @{
+ */
+
+/**
+ * @brief Core interface configuration
+ *
+ * Core instance would have 2 endpoints (IN0 and OUT0).
+ * The interface number does not matter because it is not used.
+ */
+#define APP_USBD_CORE_CLASS_CONFIGURATION ((0, NRF_DRV_USBD_EPOUT0, NRF_DRV_USBD_EPIN0))
+
+/**
+ * @brief USB Device state
+ *
+ * Possible USB Device states according to specification.
+ */
+typedef enum
+{
+ APP_USBD_STATE_Disabled , /**< The whole USBD library is disabled */
+ APP_USBD_STATE_Unattached, /**< Device is currently not connected to the host */
+ APP_USBD_STATE_Powered , /**< Device is connected to the host but has not been enumerated */
+ APP_USBD_STATE_Default , /**< USB Reset condition detected, waiting for the address */
+ APP_USBD_STATE_Addressed , /**< Device has been addressed but has not been configured */
+ APP_USBD_STATE_Configured, /**< Device is addressed and configured */
+}app_usbd_state_t;
+
+/**
+ * @brief EP0 handler function pointer
+ *
+ * Type of the variable that would hold the pointer to the handler for
+ * endpoint 0 messages processing.
+ *
+ * @param p_contex Context variable configured with the transmission request.
+ */
+typedef ret_code_t (*app_usbd_core_setup_data_handler_t)(nrf_drv_usbd_ep_status_t status,
+ void * p_context);
+
+/**
+ * @brief Variable type used to register EP0 transfer handler
+ *
+ * EP0 messages are processed by core instance.
+ * Another class can register itself to receive messages from EP0 when requesting
+ * for Setup data transfer.
+ */
+typedef struct
+{
+ app_usbd_core_setup_data_handler_t handler; //!< Event handler to be called when transmission is ready
+ void * p_context; //!< Context pointer to be send to every called event.
+} app_usbd_core_setup_data_handler_desc_t;
+
+/*lint -save -e10 -e26 -e93 -e123 -e505 */
+/**
+ * @brief Declare Core instance type
+ *
+ * USBD core instance type definition.
+ */
+APP_USBD_CLASS_TYPEDEF(app_usbd_core,
+ APP_USBD_CORE_CLASS_CONFIGURATION,
+ APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE);
+/*lint -restore*/
+
+/**
+ * @brief Access to core instance
+ *
+ * Function that returns pointer to the USBD core instance.
+ *
+ * @return pointer to the core instance
+ */
+static inline app_usbd_class_inst_t const * app_usbd_core_instance_access(void)
+{
+ extern const APP_USBD_CLASS_INSTANCE_TYPE(app_usbd_core) app_usbd_core_inst;
+ return (app_usbd_class_inst_t const *)&app_usbd_core_inst;
+}
+
+/**
+ * @brief Default simple response to setup command
+ *
+ * This function generates default simple response.
+ * It sends ZLP when required and on takes care on allowing status stage when
+ * transfer is finished.
+ *
+ * @param p_setup Pointer to original setup message
+ * @param p_data Pointer to the response. This has to be globaly aviable data.
+ * @param size Total size of the answer - The function takes care about
+ * limiting the size of transfered data to the size required
+ * by setup command.
+ */
+ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup,
+ void const * p_data,
+ size_t size);
+
+/**
+ * @brief Configure the handler for the nearest setup data endpoint transfer
+ *
+ * This function would be called on incomming setup data.
+ * The correct place to set the handler for a data is when SETUP command
+ * was received.
+ *
+ * @param ep Endpoint number (only IN0 and OUT0) are supported.
+ * @param p_handler_desc Descriptor of the handler to be called.
+ *
+ * @retval NRF_SUCCESS Successfully configured
+ * @retval NRF_ERROR_INVALID_ADDR Last received setup direction does not match
+ * configured endpoint.
+ */
+ret_code_t app_usbd_core_setup_data_handler_set(
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc);
+
+/**
+ * @brief Set up a data transfer buffer.
+ *
+ * Returns special internal buffer that can be used in setup transfer.
+ * @return Internal buffer pointer
+ */
+void * app_usbd_core_setup_transfer_buff_get(size_t * p_size);
+
+
+/**@brief Return internal USBD core state
+ *
+ * @return Check @ref app_usbd_state_t to find possible USBD core states
+ */
+app_usbd_state_t app_usbd_core_state_get(void);
+
+
+/**
+ * @brief Check current feature state
+ *
+ * Function checks the state of the selected feature that was configured by the host.
+ *
+ * @param feature Feature to check.
+ * Only features related to the device should be checked by this function.
+ *
+ * @retval true Selected feature is set
+ * @retval false Selected feature is cleared
+ */
+bool app_usbd_core_feature_state_get(app_usbd_setup_stdfeature_t feature);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CORE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h
new file mode 100644
index 0000000..4d3dded
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h
@@ -0,0 +1,337 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_DESCRIPTOR_H__
+#define APP_USBD_DESCRIPTOR_H__
+
+#include "nrf.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_langid.h"
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Compiler support for anonymous unions */
+ANON_UNIONS_ENABLE;
+
+/**
+ * @defgroup app_usbd_descriptor USB standard descriptors
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types definitions used for standard descriptors.
+ * @{
+ */
+
+/**
+ * @brief Helper macro for translating unsigned 24 bit value to 2 byte raw descriptor
+ * */
+#define APP_USBD_U16_TO_RAW_DSC(val) (uint8_t)(val), \
+ (uint8_t)(((val) / (256)))
+
+/**
+ * @brief Helper macro for translating unsigned 24 bit value to 3 byte raw descriptor
+ * */
+#define APP_USBD_U24_TO_RAW_DSC(val) (uint8_t)(val), \
+ (uint8_t)(((val) / (256))), \
+ (uint8_t)(((val) / (256 * 256)))
+
+/**
+ * @brief Helper macro for translating unsigned 32 bit value to 4 byte raw descriptor
+ * */
+#define APP_USBD_U32_TO_RAW_DSC(val) (uint8_t)(val), \
+ (uint8_t)(((val) / (256))), \
+ (uint8_t)(((val) / (256 * 256))) \
+ (uint8_t)(((val) / (256 * 256 * 256)))
+/**
+ * @brief Descriptor types
+ *
+ * Descriptor types used in two situations:
+ * - when processing @ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR SETUP request,
+ * the required descriptor type may be placed in wValue in HighByte.
+ * - As a descriptor identifier itself inside descriptor stream.
+ *
+ * According to chapter 9.6 of USB 2.0 specification, following descriptors may
+ * be requested directly by GetDescriptor method:
+ * - @ref APP_USBD_DESCRIPTOR_DEVICE
+ * - @ref APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER (not used for FullSpeed only device)
+ * - @ref APP_USBD_DESCRIPTOR_CONFIGURATION
+ * - @ref APP_USBD_DESCRIPTOR_STRING
+ */
+typedef enum
+{
+ APP_USBD_DESCRIPTOR_DEVICE = 1, /**< Device descriptor. */
+ APP_USBD_DESCRIPTOR_CONFIGURATION = 2, /**<
+ * Specific configuration descriptor.
+ * Configuration descriptor is always followed by all the related interface
+ * and endpoints descriptors.
+ */
+ APP_USBD_DESCRIPTOR_STRING = 3, /**< String descriptor. */
+ APP_USBD_DESCRIPTOR_INTERFACE = 4, /**<
+ * Interface descriptor followed by all the related endpoints descriptors.
+ *
+ * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
+ * Cannot be accessed by GetDescriptor or SetDescriptor
+ */
+ APP_USBD_DESCRIPTOR_ENDPOINT = 5, /**<
+ * Endpoint descriptor.
+ *
+ * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
+ * Cannot be accessed by GetDescriptor or SetDescriptor
+ */
+ APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER = 6, /**< @note Not supported - used only in HighSpeed capable devices. */
+ APP_USBD_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7, /**< @note Not supported - our USB implementation supports only one speed. */
+ APP_USBD_DESCRIPTOR_INTERFACE_POWER = 8, /**< @note Not supported */
+ APP_USBD_DESCRIPTOR_OTG = 9, /**< @note Not supported - Our USB have not OTG functionality */
+ APP_USBD_DESCRIPTOR_DEBUG = 10, /**< Debug channel descriptor if available, can be only reached by GetDescriptor */
+ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION = 11, /**<
+ * Descriptor used to describe that two or more interfaces are associated to the same function.
+ *
+ * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
+ * Cannot be accessed by GetDescriptor or SetDescriptor
+ */
+ APP_USBD_DESCRIPTOR_REPORT = 34, /**< HID Report descriptor. */
+ APP_USBD_DESCRIPTOR_PHYSICAL = 35 /**< HID Physical descriptor. */
+
+} app_usbd_descriptor_t;
+
+/* Make all descriptors packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Common descriptor header
+ *
+ * The header that we can find on the beginning of all descriptors that contains
+ * the descriptor length and type.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal one of @ref app_usbd_descriptor_t.
+ /** Class specific descriptors values are defined inside classes. */
+} app_usbd_descriptor_header_t;
+
+/**
+ * @brief Device descriptor
+ *
+ * Descriptor used for the whole device
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
+ uint16_t bcdUSB; //!< USB Specification Release Number in Binary-Coded Decimal
+ uint8_t bDeviceClass; //!< Device class code.
+ /**< If 0, each interface specifies its own class information.
+ * 0xFF for vendor-specific.
+ */
+ uint8_t bDeviceSubClass; //!< Subclass code.
+ /**< If bDevice Class is set to value other than 0xFF,
+ * all values here are reserved for assignment by USB-IF.
+ */
+ uint8_t bDeviceProtocol; //!< Subclass code.
+ /**< If 0, no specific protocol is defined on device basis.
+ * Each interface may define its own protocol then.
+ * If set to 0xFF, vendor-specific protocol is used.
+ */
+ uint8_t bMaxPacketSize0; //!< Maximum packet size for endpoint zero.
+ uint16_t idVendor; //!< Vendor ID (Assigned by the USB-IF).
+ uint16_t idProduct; //!< Product ID (assigned by manufacturer).
+ uint16_t bcdDevice; //!< Device release number in binary-coded decimal.
+ uint8_t iManufacturer; //!< Index of string descriptor in describing manufacturer.
+ uint8_t iProduct; //!< Index of string descriptor in describing product.
+ uint8_t iSerialNumber; //!< Index of string descriptor in describing the device's serial number.
+ uint8_t bNumConfigurations; //!< Number of possible configurations.
+} app_usbd_descriptor_device_t;
+
+/**
+ * @brief Attributes masks
+ *
+ * Masks used for attributes in configuration.
+ */
+typedef enum
+{
+ /** This is reserved descriptor that has always to be set */
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK = 1U << 7,
+ /** Attribute that informs that device is self powered */
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK = 1U << 6,
+ /** Attribute that informs that device has Remove Wakeup functionality */
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK = 1U << 5
+} app_usbd_descriptor_configuration_attributes_t;
+
+/**
+ * @brief Configuration descriptor
+ *
+ * Descriptor used at the beginning of configuration response.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
+ uint16_t wTotalLength; //!< Total length of configuration data, including all descriptors returned after configuration itself.
+ uint8_t bNumInterfaces; //!< Number of interfaces supportedf by this configuration
+ uint8_t bConfigurationValue; //!< Value to use as an argument to the SetConfiguration request.
+ uint8_t iConfiguration; //!< Index of string descriptor describing this configuration.
+ uint8_t bmAttributes; //!< Configuration characteristics.
+ uint8_t bMaxPower; //!< Maximum power consumption. Expressed in 2&nbsp;mA units.
+} app_usbd_descriptor_configuration_t;
+
+/**
+ * @brief Raw descriptor - String descriptor zero
+ *
+ * String descriptor sent only as a response for GetDescriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
+ uint16_t wLANGID[]; //!< The array of LANGID codes supported by the device.
+} app_usbd_descriptor_string0_t;
+
+/**
+ * @brief Raw descriptor - Any normal string
+ *
+ * String descriptor sent only as a response for GetDescriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
+ uint16_t bString[]; //!< UNICODE encoded string.
+} app_usbd_descriptor_string_t;
+
+
+/**
+ * @brief Interface descriptor
+ *
+ * Interface descriptor, returned as a part of configuration descriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_INTERFACE.
+ uint8_t bInterfaceNumber; //!< Number of this interface.
+ uint8_t bAlternateSetting; //!< Value used to select this alternate setting.
+ uint8_t bNumEndpoints; //!< Number of endpoints used by this interface.
+ uint8_t bInterfaceClass; //!< Class code (assigned by the USB-IF). 0xff for vendor specific.
+ uint8_t bInterfaceSubClass; //!< Subclass code (assigned by the USB-IF).
+ uint8_t bInterfaceProtocol; //!< Protocol code (assigned by the USB-IF). 0xff for vendor specific.
+ uint8_t iInterface; //!< Index of string descriptor describing this interface.
+} app_usbd_descriptor_iface_t;
+
+/** Offset of endpoint type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET 0
+/** Mask of endpoint type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET)
+
+/** Offset of endpoint synchronization type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET 2
+/** Mask of endpoint synchronization type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET)
+
+/** Offset of endpoint usage type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET 4
+/** Mask of endpoint usage type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET)
+
+/**
+ * @brief Endpoint attributes mnemonics
+ *
+ * @sa APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK
+ * @sa APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK
+ * @sa APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK
+ */
+typedef enum
+{
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_CONTROL = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_NONE = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ASYNCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ADAPTIVE = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_SYNCHRONOUS = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+
+ APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_DATA = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_FEEDBACK = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_IMPLICIT = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET
+} app_usbd_descriptor_ep_attr_bitmap_t;
+
+/**
+ * @brief Endpoint descriptor
+ *
+ * Endpoint descriptor, returned as a part of configuration descriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_ENDPOINT.
+ uint8_t bEndpointAddress; //!< Endpoint address
+ uint8_t bmAttributes; //!< Endpoint attributes
+ uint16_t wMaxPacketSize; //!< Maximum packet size this endpoint is capable of handling.
+ uint8_t bInterval; //!< Interval for pooling endpoint for data transfers.
+} app_usbd_descriptor_ep_t;
+
+/**
+ * @brief Interface association descriptor
+ */
+typedef struct
+{
+ uint8_t bLength; //!< size of this descriptor in bytes
+ uint8_t bDescriptorType; //!< INTERFACE descriptor type
+ uint8_t bFirstInterface; //!< Number of interface
+ uint8_t bInterfaceCount; //!< value to select alternate setting
+ uint8_t bFunctionClass; //!< Class code assigned by the USB
+ uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB
+ uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB
+ uint8_t iFunction; //!< Index of string descriptor
+} app_usbd_descriptor_iad_t;
+
+#pragma pack(pop)
+ANON_UNIONS_DISABLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* APP_USBD_DESCRIPTOR_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h
new file mode 100644
index 0000000..0d08f14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_LANGID_H__
+#define APP_USBD_LANGID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * @brief This file contains LANGID variable type with all defined values
+ *
+ * This file was created using Language Identifiers (LANGIDs) 3/29/00 Version 1.0,
+ * available on USB web page:
+ * http://www.usb.org/developers/docs/USB_LANGIDs.pdf
+ *
+ * @note
+ * Do not include this file directly to the project.
+ * It is included by @file app_usbd_request.h.
+ */
+
+/**
+ * Offset of the lowest bit of primary language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_LANG_OFFSET 0
+
+/**
+ * Bitmask for a primary language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_LANG_MASK BF_MASK(10, APP_USB_LANG_OFFSET)
+
+/**
+ * Offset of the lowest bit of sub-language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_SUBLANG_OFFSET 10
+
+/**
+ * Bitmask for a sub-language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_SUBLANG_MASK BF_MASK(6, APP_USB_SUBLANG_OFFSET)
+
+/**
+ * @brief Primary language identifiers
+ *
+ * Mnemonics for primary language identifiers.
+ * This mnemonics can be combined using logical OR operator with @ref app_usbd_langid_sub_t.
+ */
+typedef enum
+{
+ APP_USBD_LANG_ARABIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic */
+ APP_USBD_LANG_BULGARIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Bulgarian */
+ APP_USBD_LANG_CATALAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Catalan */
+ APP_USBD_LANG_CHINESE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese */
+ APP_USBD_LANG_CZECH = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Czech */
+ APP_USBD_LANG_DANISH = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Danish */
+ APP_USBD_LANG_GERMAN = 0x07U << ( APP_USB_LANG_OFFSET ), /**< German */
+ APP_USBD_LANG_GREEK = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Greek */
+ APP_USBD_LANG_ENGLISH = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English */
+ APP_USBD_LANG_SPANISH = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish */
+ APP_USBD_LANG_FINNISH = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Finnish */
+ APP_USBD_LANG_FRENCH = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< French */
+ APP_USBD_LANG_HEBREW = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Hebrew */
+ APP_USBD_LANG_HUNGARIAN = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Hungarian */
+ APP_USBD_LANG_ICELANDIC = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Icelandic */
+ APP_USBD_LANG_ITALIAN = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Italian */
+ APP_USBD_LANG_JAPANESE = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Japanese */
+ APP_USBD_LANG_KOREAN = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Korean */
+ APP_USBD_LANG_DUTCH = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Dutch */
+ APP_USBD_LANG_NORWEGIAN = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Norwegian */
+ APP_USBD_LANG_POLISH = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Polish */
+ APP_USBD_LANG_PORTUGUESE = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */
+ APP_USBD_LANG_ROMANIAN = 0x18U << ( APP_USB_LANG_OFFSET ), /**< Romanian */
+ APP_USBD_LANG_RUSSIAN = 0x19U << ( APP_USB_LANG_OFFSET ), /**< Russian */
+ APP_USBD_LANG_CROATIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Croatian */
+ APP_USBD_LANG_SERBIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Serbian */
+ APP_USBD_LANG_SLOVAK = 0x1bU << ( APP_USB_LANG_OFFSET ), /**< Slovak */
+ APP_USBD_LANG_ALBANIAN = 0x1cU << ( APP_USB_LANG_OFFSET ), /**< Albanian */
+ APP_USBD_LANG_SWEDISH = 0x1dU << ( APP_USB_LANG_OFFSET ), /**< Swedish */
+ APP_USBD_LANG_THAI = 0x1eU << ( APP_USB_LANG_OFFSET ), /**< Thai */
+ APP_USBD_LANG_TURKISH = 0x1fU << ( APP_USB_LANG_OFFSET ), /**< Turkish */
+ APP_USBD_LANG_URDU = 0x20U << ( APP_USB_LANG_OFFSET ), /**< Urdu */
+ APP_USBD_LANG_INDONESIAN = 0x21U << ( APP_USB_LANG_OFFSET ), /**< Indonesian */
+ APP_USBD_LANG_UKRANIAN = 0x22U << ( APP_USB_LANG_OFFSET ), /**< Ukrainian */
+ APP_USBD_LANG_BELARUSIAN = 0x23U << ( APP_USB_LANG_OFFSET ), /**< Belarusian */
+ APP_USBD_LANG_SLOVENIAN = 0x24U << ( APP_USB_LANG_OFFSET ), /**< Slovenian */
+ APP_USBD_LANG_ESTONIAN = 0x25U << ( APP_USB_LANG_OFFSET ), /**< Estonian */
+ APP_USBD_LANG_LATVIAN = 0x26U << ( APP_USB_LANG_OFFSET ), /**< Latvian */
+ APP_USBD_LANG_LITHUANIAN = 0x27U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */
+ APP_USBD_LANG_FARSI = 0x29U << ( APP_USB_LANG_OFFSET ), /**< Farsi */
+ APP_USBD_LANG_VIETNAMESE = 0x2aU << ( APP_USB_LANG_OFFSET ), /**< Vietnamese */
+ APP_USBD_LANG_ARMENIAN = 0x2bU << ( APP_USB_LANG_OFFSET ), /**< Armenian */
+ APP_USBD_LANG_AZERI = 0x2cU << ( APP_USB_LANG_OFFSET ), /**< Azeri */
+ APP_USBD_LANG_BASQUE = 0x2dU << ( APP_USB_LANG_OFFSET ), /**< Basque */
+ APP_USBD_LANG_MACEDONIAN = 0x2fU << ( APP_USB_LANG_OFFSET ), /**< Macedonian */
+ APP_USBD_LANG_AFRIKAANS = 0x36U << ( APP_USB_LANG_OFFSET ), /**< Afrikaans */
+ APP_USBD_LANG_GEORGIAN = 0x37U << ( APP_USB_LANG_OFFSET ), /**< Georgian */
+ APP_USBD_LANG_FAEROESE = 0x38U << ( APP_USB_LANG_OFFSET ), /**< Faeroese */
+ APP_USBD_LANG_HINDI = 0x39U << ( APP_USB_LANG_OFFSET ), /**< Hindi */
+ APP_USBD_LANG_MALAY = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< Malay */
+ APP_USBD_LANG_KAZAK = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< Kazak */
+ APP_USBD_LANG_SWAHILI = 0x41U << ( APP_USB_LANG_OFFSET ), /**< Swahili */
+ APP_USBD_LANG_UZBEK = 0x43U << ( APP_USB_LANG_OFFSET ), /**< Uzbek */
+ APP_USBD_LANG_TATAR = 0x44U << ( APP_USB_LANG_OFFSET ), /**< Tatar */
+ APP_USBD_LANG_BENGALI = 0x45U << ( APP_USB_LANG_OFFSET ), /**< Bengali */
+ APP_USBD_LANG_PUNJABI = 0x46U << ( APP_USB_LANG_OFFSET ), /**< Punjabi */
+ APP_USBD_LANG_GUJARATI = 0x47U << ( APP_USB_LANG_OFFSET ), /**< Gujarati */
+ APP_USBD_LANG_ORIYA = 0x48U << ( APP_USB_LANG_OFFSET ), /**< Oriya */
+ APP_USBD_LANG_TAMIL = 0x49U << ( APP_USB_LANG_OFFSET ), /**< Tamil */
+ APP_USBD_LANG_TELUGU = 0x4aU << ( APP_USB_LANG_OFFSET ), /**< Telugu */
+ APP_USBD_LANG_KANNADA = 0x4bU << ( APP_USB_LANG_OFFSET ), /**< Kannada */
+ APP_USBD_LANG_MALAYALAM = 0x4cU << ( APP_USB_LANG_OFFSET ), /**< Malayalam */
+ APP_USBD_LANG_ASSAMESE = 0x4dU << ( APP_USB_LANG_OFFSET ), /**< Assamese */
+ APP_USBD_LANG_MARATHI = 0x4eU << ( APP_USB_LANG_OFFSET ), /**< Marathi */
+ APP_USBD_LANG_SANSKRIT = 0x4fU << ( APP_USB_LANG_OFFSET ), /**< Sanskrit */
+ APP_USBD_LANG_KONKANI = 0x57U << ( APP_USB_LANG_OFFSET ), /**< Konkani */
+ APP_USBD_LANG_MANIPURI = 0x58U << ( APP_USB_LANG_OFFSET ), /**< Manipuri */
+ APP_USBD_LANG_SINDHI = 0x59U << ( APP_USB_LANG_OFFSET ), /**< Sindhi */
+ APP_USBD_LANG_KASHMIRI = 0x60U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri */
+ APP_USBD_LANG_NEPALI = 0x61U << ( APP_USB_LANG_OFFSET ), /**< Nepali */
+ APP_USBD_LANG_HID = 0xffU << ( APP_USB_LANG_OFFSET ), /**< Reserved for USB HID Class use */
+}app_usbd_langid_primary_t;
+
+/**
+ * @brief Sublanguage identifiers
+ *
+ * Mnemonics with sublanguage values.
+ * Use them in combination with @ref app_usbd_langid_primary_t.
+ */
+typedef enum
+{
+ APP_USBD_SUBLANG_ARABIC_SAUDI_ARABIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Saudi Arabia) */
+ APP_USBD_SUBLANG_ARABIC_IRAQ = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Iraq) */
+ APP_USBD_SUBLANG_ARABIC_EGYPT = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Egypt) */
+ APP_USBD_SUBLANG_ARABIC_LIBYA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Libya) */
+ APP_USBD_SUBLANG_ARABIC_ALGERIA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Algeria) */
+ APP_USBD_SUBLANG_ARABIC_MOROCCO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Morocco) */
+ APP_USBD_SUBLANG_ARABIC_TUNISIA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Tunisia) */
+ APP_USBD_SUBLANG_ARABIC_OMAN = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Oman) */
+ APP_USBD_SUBLANG_ARABIC_YEMEN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Yemen) */
+ APP_USBD_SUBLANG_ARABIC_SYRIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Syria) */
+ APP_USBD_SUBLANG_ARABIC_JORDAN = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Jordan) */
+ APP_USBD_SUBLANG_ARABIC_LEBANON = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Lebanon) */
+ APP_USBD_SUBLANG_ARABIC_KUWAIT = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Kuwait) */
+ APP_USBD_SUBLANG_ARABIC_UAE = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Arabic (U.A.E.) */
+ APP_USBD_SUBLANG_ARABIC_BAHRAIN = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Bahrain) */
+ APP_USBD_SUBLANG_ARABIC_QATAR = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Qatar) */
+ APP_USBD_SUBLANG_AZERI_CYRILLIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Cyrillic) */
+ APP_USBD_SUBLANG_AZERI_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Latin) */
+ APP_USBD_SUBLANG_CHINESE_TRADITIONAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Traditional) */
+ APP_USBD_SUBLANG_CHINESE_SIMPLIFIED = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Simplified) */
+ APP_USBD_SUBLANG_CHINESE_HONGKONG = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Hong Kong SAR, PRC) */
+ APP_USBD_SUBLANG_CHINESE_SINGAPORE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Singapore) */
+ APP_USBD_SUBLANG_CHINESE_MACAU = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Macau SAR) */
+ APP_USBD_SUBLANG_DUTCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Dutch */
+ APP_USBD_SUBLANG_DUTCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Dutch (Belgian) */
+ APP_USBD_SUBLANG_ENGLISH_US = 0x01U << ( APP_USB_LANG_OFFSET ), /**< English (US) */
+ APP_USBD_SUBLANG_ENGLISH_UK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< English (UK) */
+ APP_USBD_SUBLANG_ENGLISH_AUS = 0x03U << ( APP_USB_LANG_OFFSET ), /**< English (Australian) */
+ APP_USBD_SUBLANG_ENGLISH_CAN = 0x04U << ( APP_USB_LANG_OFFSET ), /**< English (Canadian) */
+ APP_USBD_SUBLANG_ENGLISH_NZ = 0x05U << ( APP_USB_LANG_OFFSET ), /**< English (New Zealand) */
+ APP_USBD_SUBLANG_ENGLISH_EIRE = 0x06U << ( APP_USB_LANG_OFFSET ), /**< English (Ireland) */
+ APP_USBD_SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< English (South Africa) */
+ APP_USBD_SUBLANG_ENGLISH_JAMAICA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< English (Jamaica) */
+ APP_USBD_SUBLANG_ENGLISH_CARIBBEAN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English (Caribbean) */
+ APP_USBD_SUBLANG_ENGLISH_BELIZE = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< English (Belize) */
+ APP_USBD_SUBLANG_ENGLISH_TRINIDAD = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< English (Trinidad) */
+ APP_USBD_SUBLANG_ENGLISH_PHILIPPINES = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< English (Zimbabwe) */
+ APP_USBD_SUBLANG_ENGLISH_ZIMBABWE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< English (Philippines) */
+ APP_USBD_SUBLANG_FRENCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< French */
+ APP_USBD_SUBLANG_FRENCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< French (Belgian) */
+ APP_USBD_SUBLANG_FRENCH_CANADIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< French (Canadian) */
+ APP_USBD_SUBLANG_FRENCH_SWISS = 0x04U << ( APP_USB_LANG_OFFSET ), /**< French (Swiss) */
+ APP_USBD_SUBLANG_FRENCH_LUXEMBOURG = 0x05U << ( APP_USB_LANG_OFFSET ), /**< French (Luxembourg) */
+ APP_USBD_SUBLANG_FRENCH_MONACO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< French (Monaco) */
+ APP_USBD_SUBLANG_GERMAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< German */
+ APP_USBD_SUBLANG_GERMAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< German (Swiss) */
+ APP_USBD_SUBLANG_GERMAN_AUSTRIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< German (Austrian) */
+ APP_USBD_SUBLANG_GERMAN_LUXEMBOURG = 0x04U << ( APP_USB_LANG_OFFSET ), /**< German (Luxembourg) */
+ APP_USBD_SUBLANG_GERMAN_LIECHTENSTEIN = 0x05U << ( APP_USB_LANG_OFFSET ), /**< German (Liechtenstein) */
+ APP_USBD_SUBLANG_ITALIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Italian */
+ APP_USBD_SUBLANG_ITALIAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Italian (Swiss) */
+ APP_USBD_SUBLANG_KASHMIRI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri (India) */
+ APP_USBD_SUBLANG_KOREAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Korean */
+ APP_USBD_SUBLANG_LITHUANIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */
+ APP_USBD_SUBLANG_MALAY_MALAYSIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Malay (Malaysia) */
+ APP_USBD_SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Malay (Brunei Darassalam) */
+ APP_USBD_SUBLANG_NEPALI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Nepali (India) */
+ APP_USBD_SUBLANG_NORWEGIAN_BOKMAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Bokmal) */
+ APP_USBD_SUBLANG_NORWEGIAN_NYNORSK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Nynorsk) */
+ APP_USBD_SUBLANG_PORTUGUESE = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Portuguese (Brazilian) */
+ APP_USBD_SUBLANG_PORTUGUESE_BRAZILIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */
+ APP_USBD_SUBLANG_SERBIAN_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Latin) */
+ APP_USBD_SUBLANG_SERBIAN_CYRILLIC = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Cyrillic) */
+ APP_USBD_SUBLANG_SPANISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Castilian) */
+ APP_USBD_SUBLANG_SPANISH_MEXICAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Mexican) */
+ APP_USBD_SUBLANG_SPANISH_MODERN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Modern) */
+ APP_USBD_SUBLANG_SPANISH_GUATEMALA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Guatemala) */
+ APP_USBD_SUBLANG_SPANISH_COSTA_RICA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Costa Rica) */
+ APP_USBD_SUBLANG_SPANISH_PANAMA = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Panama) */
+ APP_USBD_SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Dominican Republic) */
+ APP_USBD_SUBLANG_SPANISH_VENEZUELA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Venezuela) */
+ APP_USBD_SUBLANG_SPANISH_COLOMBIA = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Colombia) */
+ APP_USBD_SUBLANG_SPANISH_PERU = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Peru) */
+ APP_USBD_SUBLANG_SPANISH_ARGENTINA = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Argentina) */
+ APP_USBD_SUBLANG_SPANISH_ECUADOR = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Ecuador) */
+ APP_USBD_SUBLANG_SPANISH_CHILE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Chile) */
+ APP_USBD_SUBLANG_SPANISH_URUGUAY = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Uruguay) */
+ APP_USBD_SUBLANG_SPANISH_PARAGUAY = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Paraguay) */
+ APP_USBD_SUBLANG_SPANISH_BOLIVIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Bolivia) */
+ APP_USBD_SUBLANG_SPANISH_EL_SALVADOR = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Spanish (El Salvador) */
+ APP_USBD_SUBLANG_SPANISH_HONDURAS = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Honduras) */
+ APP_USBD_SUBLANG_SPANISH_NICARAGUA = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Nicaragua) */
+ APP_USBD_SUBLANG_SPANISH_PUERTO_RICO = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Puerto Rico) */
+ APP_USBD_SUBLANG_SWEDISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Swedish */
+ APP_USBD_SUBLANG_SWEDISH_FINLAND = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Swedish (Finland) */
+ APP_USBD_SUBLANG_URDU_PAKISTAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Urdu (Pakistan) */
+ APP_USBD_SUBLANG_URDU_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Urdu (India) */
+ APP_USBD_SUBLANG_UZBEK_LATIN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Latin) */
+ APP_USBD_SUBLANG_UZBEK_CYRILLIC = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Cyrillic) */
+ APP_USBD_SUBLANG_HID_USAGE_DATA_DESCRIPTOR = 0x01U << ( APP_USB_LANG_OFFSET ), /**< HID (Usage Data Descriptor) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_1 = 0x3cU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 1) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_2 = 0x3dU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 2) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_3 = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 3) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_4 = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 4) */
+}app_usbd_langid_sub_t;
+
+/**
+ * @brief LANGID variable
+ *
+ * The LANGID value is composed from:
+ * - 10-bit (9-0) of Primary Language Identifiers
+ * - 6-bit (15-10) of Sublanguage Identifiers.
+ *
+ * @sa app_usbd_langid_primary_t
+ * @sa app_usbd_langid_sub_t
+ */
+typedef uint16_t app_usbd_langid_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_LANGID_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h
new file mode 100644
index 0000000..d2f6f14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h
@@ -0,0 +1,356 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_REQUEST_H__
+#define APP_USBD_REQUEST_H__
+
+#include "sdk_common.h"
+#include "nrf.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_descriptor.h"
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Compiler support for anonymous unions */
+ANON_UNIONS_ENABLE;
+
+#pragma pack(push, 1)
+
+/**
+ * @defgroup app_usbd_request USB standard requests
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types definitions used for standard requests processing.
+ * @{
+ */
+
+/**
+ * @brief Recipient bit-field in request type
+ *
+ * Bits 4...0
+ */
+#define APP_USBD_SETUP_REQ_BF_REC BF_CX(5, 0)
+
+/**
+ * @brief Type bit-field in request type
+ *
+ * Bits 6...5
+ */
+#define APP_USBD_SETUP_REQ_BF_TYP BF_CX(2, 5)
+
+/**
+ * @brief Direction bit-field in request type
+ *
+ * Bit 7
+ */
+#define APP_USBD_SETUP_REQ_BF_DIR BF_CX(1, 7)
+
+/**
+ * @brief Recipient enumerator.
+ *
+ * @note It is part of @ref app_usbd_setup_reqtype_t variable type.
+ */
+typedef enum {
+ APP_USBD_SETUP_REQREC_DEVICE = 0x0, /**< The whole device is a request target */
+ APP_USBD_SETUP_REQREC_INTERFACE = 0x1, /**< Selected interface is a request target */
+ APP_USBD_SETUP_REQREC_ENDPOINT = 0x2, /**< Selected endpoint is a request target */
+ APP_USBD_SETUP_REQREC_OTHER = 0x3 /**< Other element is a request target */
+} app_usbd_setup_reqrec_t;
+
+/**
+ * @brief Request type enumerator.
+ *
+ * @note It is part of @ref app_usbd_setup_reqtype_t variable type.
+ */
+typedef enum {
+ APP_USBD_SETUP_REQTYPE_STD = 0x0, /**< Standard request */
+ APP_USBD_SETUP_REQTYPE_CLASS = 0x1, /**< Class specific request */
+ APP_USBD_SETUP_REQTYPE_VENDOR = 0x2 /**< Vendor specific request */
+} app_usbd_setup_reqtype_t;
+
+/**
+ * @brief Direction of setup command
+ *
+ * @note It is part of @ref app_usbd_setup_reqtype_t variable type.
+ */
+typedef enum {
+ APP_USBD_SETUP_REQDIR_OUT = 0x0, /**< Host to device */
+ APP_USBD_SETUP_REQDIR_IN = 0x1, /**< Device to host */
+} app_usbd_setup_reqdir_t;
+
+
+/**
+ * @brief Standard requests
+ *
+ * Enumerator for standard requests values
+ */
+typedef enum {
+ APP_USBD_SETUP_STDREQ_GET_STATUS = 0x00, /**<
+ * Targets: Device, Interface, Endpoint
+ * Expected SETUP frame format:
+ * - wValue: Zero
+ * - wIndex: Zero, (lb): Interface or Endpoint
+ * - wLength: 2
+ * - Data:2 bytes of data, depending on targets
+ * - Device:
+ * - D15..D2: Reserved (Reset to zero)
+ * - D1: Remove Wakeup
+ * - D0: Self Powered
+ * - Interface:
+ * - D15..D0: Reserved (Reset to zero)
+ * - Endpoint:
+ * - D15..D1: Reserved (Reset to zero)
+ * - D0: Halt
+ */
+ APP_USBD_SETUP_STDREQ_CLEAR_FEATURE = 0x01, /**<
+ * Targets: Device, Interface, Endpoint
+ * Expected SETUP frame format:
+ * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t)
+ * - wIndex: Zero, Interface or Endpoint
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_SET_FEATURE = 0x03, /**<
+ * Targets: Device, Interface, Endpoint
+ * Expected SETUP frame format:
+ * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t)
+ * - wIndex: Zero, Interface or Endpoint
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_SET_ADDRESS = 0x05, /**<
+ * @note This SETUP request is processed in hardware.
+ * Use it only to mark current USB state.
+ *
+ * Targets: Device
+ * Expected SETUP frame format:
+ * - wValue: New device address
+ * - wIndex: 0
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR = 0x06, /**<
+ * Targets: Device
+ * - wValue: (hb): Descriptor Type and (lb): Descriptor Index
+ * - wIndex: Zero of Language ID
+ * - wLength: Descriptor Length
+ * - Data: Descriptor
+ */
+ APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR = 0x07, /**<
+ * Not supported - Stall when called.
+ */
+ APP_USBD_SETUP_STDREQ_GET_CONFIGURATION = 0x08, /**<
+ * Target: Device
+ * Expected SETUP frame format:
+ * - wValue: 0
+ * - wIndex: 0
+ * - wLength: 1
+ * - Data: Configuration value
+ */
+ APP_USBD_SETUP_STDREQ_SET_CONFIGURATION = 0x09, /**<
+ * Target: Device
+ * Expected SETUP frame format:
+ * - wValue: (lb): Configuration value
+ * - wIndex: 0
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_GET_INTERFACE = 0x0A, /**<
+ * Target: Interface
+ * Expected SETUP frame format:
+ * - wValue: 0
+ * - wIndex: Interface
+ * - wLength: 1
+ * - Data: Alternate setting
+ */
+ APP_USBD_SETUP_STDREQ_SET_INTERFACE = 0x0B, /**<
+ * Target: Interface
+ * Expected SETUP frame format:
+ * - wValue: Alternate setting
+ * - wIndex: Interface
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_SYNCH_FRAME = 0x0C /**<
+ * Target: Endpoint
+ * Expected SETUP frame format:
+ * - wValue: 0
+ * - wIndex: Endpoint
+ * - wLength: 2
+ * - Data: Frame Number
+ *
+ * @note
+ * This request is used only in connection with isochronous endpoints.
+ * This is rarely used and probably we would not need to support it.
+ */
+} app_usbd_setup_stdrequest_t;
+
+/**
+ * @brief Standard feature selectors
+ *
+ * Standard features that may be disabled or enabled by
+ * @ref APP_USBD_SETUP_STDREQ_CLEAR_FEATURE or @ref APP_USBD_SETUP_STDREQ_SET_FEATURE
+ */
+typedef enum {
+ APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP = 1, /**<
+ * Remote wakeup feature.
+ * Target: Device only
+ */
+ APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT = 0, /**<
+ * Stall or clear the endpoint.
+ * Target: Endpoint different than default (0)
+ */
+ APP_USBD_SETUP_STDFEATURE_TEST_MODE = 2 /**<
+ * Upstream port test mode.
+ * Power has to be cycled to exit test mode.
+ * This feature cannot be cleared.
+ *
+ * Target: Device only
+ *
+ * @note
+ * It should only be supported by HighSpeed capable devices.
+ * Not supported in this library.
+ */
+} app_usbd_setup_stdfeature_t;
+
+
+/**
+ * @brief Universal way to access 16 bit values and its parts
+ */
+typedef union {
+ uint16_t w; //!< 16 bit access
+ struct
+ {
+ uint8_t lb; //!< Low byte access
+ uint8_t hb; //!< High byte access
+ };
+} app_usbd_setup_w_t;
+
+/**
+ * @brief Internal redefinition of setup structure
+ *
+ * Redefinition of the structure to simplify changes in the future
+ * if required - app_usbd API would present setup data using app_usbd_setup_t.
+ *
+ * The structure layout is always the same like @ref nrf_drv_usbd_setup_t
+ */
+typedef struct {
+ uint8_t bmRequestType; //!< Setup type bitfield
+ uint8_t bmRequest; //!< One of @ref app_usbd_setup_stdrequest_t values or class dependent one.
+ app_usbd_setup_w_t wValue; //!< byte 2, 3
+ app_usbd_setup_w_t wIndex; //!< byte 4, 5
+ app_usbd_setup_w_t wLength; //!< byte 6, 7
+} app_usbd_setup_t;
+
+#pragma pack(pop)
+
+
+/**
+ * @brief Extract recipient from request type
+ *
+ * @param[in] bmRequestType
+ *
+ * @return Extracted recipient field from request type value
+ */
+static inline app_usbd_setup_reqrec_t app_usbd_setup_req_rec(uint8_t bmRequestType)
+{
+ return (app_usbd_setup_reqrec_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_REC);
+}
+
+/**
+ * @brief Extract type from request type
+ *
+ * @param[in] bmRequestType
+ *
+ * @return Extracted type field from request type value
+ */
+static inline app_usbd_setup_reqtype_t app_usbd_setup_req_typ(uint8_t bmRequestType)
+{
+ return (app_usbd_setup_reqtype_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_TYP);
+}
+
+
+/**
+ * @brief Extract direction from request type
+ *
+ * @param[in] bmRequestType
+ *
+ * @return Extracted direction field from request type value
+ */
+static inline app_usbd_setup_reqdir_t app_usbd_setup_req_dir(uint8_t bmRequestType)
+{
+ return (app_usbd_setup_reqdir_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_DIR);
+}
+
+/**
+ * @brief Make request type value
+ *
+ * @param[in] rec Recipient
+ * @param[in] typ Request type
+ * @param[in] dir Direction
+ *
+ * @return Assembled request type value
+ */
+static inline uint8_t app_usbd_setup_req_val(app_usbd_setup_reqrec_t rec,
+ app_usbd_setup_reqtype_t typ,
+ app_usbd_setup_reqdir_t dir)
+{
+ uint32_t bmRequestType = (
+ BF_CX_VAL(rec, APP_USBD_SETUP_REQ_BF_REC) |
+ BF_CX_VAL(typ, APP_USBD_SETUP_REQ_BF_TYP) |
+ BF_CX_VAL(dir, APP_USBD_SETUP_REQ_BF_DIR)
+ );
+
+ ASSERT(bmRequestType < 256U);
+ return (uint8_t)bmRequestType;
+}
+
+
+ANON_UNIONS_DISABLE;
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_REQUEST_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c
new file mode 100644
index 0000000..bec2f4e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "app_usbd_serial_num.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "app_usbd.h"
+
+#define SERIAL_NUMBER_STRING_SIZE (12)
+
+/**@brief Serial number generated
+ *
+ * Serial number generated by the @ref serial_number_string_create function
+ */
+uint16_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1];
+
+
+/**@brief Function for creating the serial number string from a regular C string.
+ *
+ * @param[in] p_serial_number_string The serial number string. Must be terminated with \0.
+ */
+static void string_create(char * p_serial_number_string)
+{
+ g_extern_serial_number[0] =
+ (uint16_t)APP_USBD_DESCRIPTOR_STRING << 8 | sizeof(g_extern_serial_number);
+
+ for (uint32_t i = 0; i < strlen(p_serial_number_string); i++)
+ {
+ g_extern_serial_number[i + 1] = (uint8_t)p_serial_number_string[i];
+ }
+}
+
+
+void app_usbd_serial_num_generate(void)
+{
+ char serial_number_string[SERIAL_NUMBER_STRING_SIZE + 1];
+ const uint16_t serial_num_high_bytes = (uint16_t)NRF_FICR->DEVICEADDR[1] | 0xC000; // The masking makes the address match the Random Static BLE address.
+ const uint32_t serial_num_low_bytes = NRF_FICR->DEVICEADDR[0];
+
+ (void)snprintf(serial_number_string,
+ SERIAL_NUMBER_STRING_SIZE + 1,
+ "%04"PRIX16"%08"PRIX32,
+ serial_num_high_bytes,
+ serial_num_low_bytes);
+
+ string_create(serial_number_string);
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h
new file mode 100644
index 0000000..ca0957c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_SERIAL_NUM_H__
+#define APP_USBD_SERIAL_NUM_H__
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_serial_num USBD serial number generator
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Generate a standard USB serial number that is unique for each device.
+ * @{
+ */
+
+/**@brief Function for generating a default serial number string based on FIRC->DEVICEADDR.
+ *
+ * After calling this function, the serial number is ready for the USB driver.
+ *
+ * The generated serial number shows up as a 12-hexidecimal-digit string with no delimiters
+ * (e.g 123456ABCDEF). The byte string is also printed on the PCA10059 dongle. It is also used as
+ * the default advertising address in the SoftDevice.
+ */
+void app_usbd_serial_num_generate(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_USBD_SERIAL_NUM_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c
new file mode 100644
index 0000000..0893b45
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#if APP_USBD_ENABLED
+#include "app_usbd_string_desc.h"
+#include "app_usbd_langid.h"
+#include "app_usbd_core.h"
+#include "nordic_common.h"
+
+/**
+ * @defgroup app_usbd_string_desc
+ * @ingroup app_usbd
+ *
+ * USBD string descriptors management
+ * @{
+ */
+
+/**
+ * @brief Array with language identifiers
+ *
+ * This array would be used to search the proper string for selected language.
+ */
+static const uint16_t m_langids[] = { APP_USBD_STRINGS_LANGIDS };
+
+/**
+ * @brief Language ID descriptor
+ *
+ * Language
+ */
+
+
+/**
+ * @brief Mnemonics for the string positions in the array
+ *
+ * The mnemonics for the indexes of the strings inside the string array.
+ */
+enum {
+ APP_USBD_STRING_ID_LANGIDS_ARRAY_POS = 0, /**< Supported language identifiers */
+ APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, /**< Manufacturer name */
+ APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, /**< Product name */
+ APP_USBD_STRING_ID_SERIAL_ARRAY_POS, /**< Serial number */
+#define X(mnemonic, str_idx, ...) CONCAT_2(mnemonic, _ARRAY_POS),
+ APP_USBD_STRINGS_USER
+#undef X
+};
+
+/**
+ * @brief String index into internal array index conversion table
+ *
+ * The array that transforms the USB string indexes into internal array position.
+ * @note Value 0 used to mark non-existing string.
+ */
+static const uint8_t m_string_translation[APP_USBD_STRING_ID_CNT] =
+{
+ [APP_USBD_STRING_ID_LANGIDS ] = APP_USBD_STRING_ID_LANGIDS_ARRAY_POS,
+ [APP_USBD_STRING_ID_MANUFACTURER] = APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS,
+ [APP_USBD_STRING_ID_PRODUCT ] = APP_USBD_STRING_ID_PRODUCT_ARRAY_POS,
+ [APP_USBD_STRING_ID_SERIAL ] = APP_USBD_STRING_ID_SERIAL_ARRAY_POS,
+#define X(mnemonic, str_idx, ...) [mnemonic] = CONCAT_2(mnemonic, _ARRAY_POS),
+ APP_USBD_STRINGS_USER
+#undef X
+};
+
+#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+#endif
+
+#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+#endif
+
+#ifndef APP_USBD_STRING_SERIAL_EXTERN
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+#endif
+
+#if APP_USBD_STRINGS_MANUFACTURER_EXTERN
+extern uint16_t APP_USBD_STRINGS_MANUFACTURER[];
+#endif
+
+#if APP_USBD_STRINGS_PRODUCT_EXTERN
+extern uint16_t APP_USBD_STRINGS_PRODUCT[];
+#endif
+
+#if APP_USBD_STRING_SERIAL_EXTERN
+extern uint16_t APP_USBD_STRING_SERIAL[];
+#endif
+
+
+/**
+ * @brief String descriptors table
+ * */
+static const uint16_t * m_string_dsc[APP_USBD_STRING_ID_CNT][ARRAY_SIZE(m_langids)] =
+{
+ [APP_USBD_STRING_ID_LANGIDS_ARRAY_POS] = { APP_USBD_STRING_DESC(APP_USBD_STRINGS_LANGIDS) },
+ [APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS] = { APP_USBD_STRINGS_MANUFACTURER },
+ [APP_USBD_STRING_ID_PRODUCT_ARRAY_POS] = { APP_USBD_STRINGS_PRODUCT },
+ [APP_USBD_STRING_ID_SERIAL_ARRAY_POS] = { APP_USBD_STRING_SERIAL },
+#define X(mnemonic, str_idx, ...) [CONCAT_2(mnemonic, _ARRAY_POS)] = { __VA_ARGS__ },
+ APP_USBD_STRINGS_USER
+#undef X
+};
+
+
+
+uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid)
+{
+ /* LANGID string */
+ if (APP_USBD_STRING_ID_LANGIDS == idx)
+ {
+ return m_string_dsc[APP_USBD_STRING_ID_LANGIDS_ARRAY_POS][0];
+ }
+
+ /* Searching for the language */
+ uint8_t lang_idx = 0;
+ if (ARRAY_SIZE(m_langids) > 1)
+ {
+ while (m_langids[lang_idx] != langid)
+ {
+ if (++lang_idx >= ARRAY_SIZE(m_langids))
+ {
+ return NULL;
+ }
+ }
+ }
+
+ /* Get the string index in array */
+ if (idx >= ARRAY_SIZE(m_string_translation))
+ {
+ return NULL;
+ }
+
+ uint8_t str_pos = m_string_translation[idx];
+ if (str_pos == 0)
+ {
+ return NULL;
+ }
+
+ uint16_t const * p_str = m_string_dsc[str_pos][lang_idx];
+ if ((ARRAY_SIZE(m_langids) > 1) && (lang_idx != 0))
+ {
+ if (p_str == NULL)
+ {
+ p_str = m_string_dsc[str_pos][0];
+ }
+ }
+
+ return p_str;
+}
+
+/** @} */
+#endif // APP_USBD_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h
new file mode 100644
index 0000000..2a4888c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_STRING_DESC_H__
+#define APP_USBD_STRING_DESC_H__
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "app_usbd.h"
+#include "app_usbd_string_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_string_desc USBD string descriptors
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 USBD string descriptors management.
+ * @{
+ */
+
+/**
+ * @brief USB string initialization
+ *
+ * Macro that creates initialization values for USB string.
+ * The format contains header and string itself.
+ * The string should be declared as an array of uint16_t type.
+ *
+ * @param[in] ... Comma separated string letters or language ID.
+ * @return String descriptor initialization data.
+ */
+#define APP_USBD_STRING_DESC(...) (const uint16_t[]){ \
+ (0xff & (sizeof((uint16_t[]){__VA_ARGS__}) + 2)) | \
+ ((uint16_t)APP_USBD_DESCRIPTOR_STRING) << 8, \
+ __VA_ARGS__ }
+
+/**
+ * @brief USB string descriptors ID's
+ */
+typedef enum {
+ APP_USBD_STRING_ID_LANGIDS = 0, /**< Supported language identifiers */
+ APP_USBD_STRING_ID_MANUFACTURER, /**< Manufacturer name */
+ APP_USBD_STRING_ID_PRODUCT, /**< Product name */
+ APP_USBD_STRING_ID_SERIAL, /**< Serial number */
+
+#define X(mnemonic, str_idx, ...) mnemonic str_idx,
+ APP_USBD_STRINGS_USER
+#undef X
+
+ APP_USBD_STRING_ID_CNT /**< Total number of identifiers */
+} app_usbd_string_desc_idx_t;
+
+/**
+ * @brief Get string descriptor
+ *
+ * @param[in] idx String descriptor index
+ * @param[in] langid Selected language for the string
+ * @return String descriptor or NULL if not exist
+ * */
+uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid);
+
+/**
+ * @brief Get string length
+ *
+ * Function to get string length from descriptor (descriptor returned by @ref app_usbd_string_desc_get)
+ *
+ * @param[in] p_str String descriptor pointer
+ * @return Total descriptor length in bytes
+ */
+static inline size_t app_usbd_string_desc_length(uint16_t const * p_str)
+{
+ return ((const app_usbd_descriptor_string_t *)p_str)->bLength;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_STRING_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h
new file mode 100644
index 0000000..afb879b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef APP_USBD_TYPES_H__
+#define APP_USBD_TYPES_H__
+
+#include <stdint.h>
+
+#include "sdk_errors.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_request.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_types USB Device high level library variable types definition
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 All types used by @ref app_usbd are defined here.
+ * This helps to avoid cross referencing into types in different files.
+ * @{
+ */
+
+/**
+ * @brief Change given value to 2 digits in BCD notation
+ *
+ * @param[in] val The decimal value to be converted in the range from 0 to 99.
+ * @return Calculated BCD value.
+ */
+#define APP_USBD_BCD_2_MAKE(val) ( \
+ ((((val) % 100) / 10) * 0x10) + \
+ ((((val) % 10) / 1) * 0x1) \
+ )
+
+/**
+ * @brief Change given decimal version values to 4 digits in BCD notation
+ *
+ * USB specification uses 4 digits BCD version notation in many descriptors.
+ * This macro changes 2 values to 4 BCD digits (one 16 bit value)
+ * that describes version in USB standard.
+ *
+ * @param[in] major Major version
+ * @param[in] minor Minor version
+ *
+ * @return Calculated 16 bit value with BCD representation of the version
+ */
+#define APP_USBD_BCD_VER_MAKE(major, minor) \
+ ((APP_USBD_BCD_2_MAKE(major) << 8) | APP_USBD_BCD_2_MAKE(minor))
+
+/**
+ * @brief Events codes
+ *
+ * Redefined application event codes
+ */
+typedef enum
+{
+ APP_USBD_EVT_DRV_SOF = NRF_DRV_USBD_EVT_SOF, /**< See documentation for @ref NRF_DRV_USBD_EVT_SOF */
+ APP_USBD_EVT_DRV_RESET = NRF_DRV_USBD_EVT_RESET, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESET */
+ APP_USBD_EVT_DRV_SUSPEND = NRF_DRV_USBD_EVT_SUSPEND, /**< See documentation for @ref NRF_DRV_USBD_EVT_SUSPEND */
+ APP_USBD_EVT_DRV_RESUME = NRF_DRV_USBD_EVT_RESUME, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESUME */
+ APP_USBD_EVT_DRV_WUREQ = NRF_DRV_USBD_EVT_WUREQ, /**< See documentation for @ref NRF_DRV_USBD_EVT_WUREQ */
+ APP_USBD_EVT_DRV_SETUP = NRF_DRV_USBD_EVT_SETUP, /**< This event type has special structure. See @ref app_usbd_setup_evt_t */
+ APP_USBD_EVT_DRV_EPTRANSFER = NRF_DRV_USBD_EVT_EPTRANSFER, /**< See documentation for @ref NRF_DRV_USBD_EVT_EPTRANSFER */
+
+ APP_USBD_EVT_FIRST_POWER, /**< First power event code - for internal static assert checking */
+
+ APP_USBD_EVT_POWER_DETECTED, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_DETECTED */
+ APP_USBD_EVT_POWER_REMOVED, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_REMOVED */
+ APP_USBD_EVT_POWER_READY, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_READY */
+
+
+ APP_USBD_EVT_FIRST_APP, /**< First application event code - for internal static assert checking */
+
+ APP_USBD_EVT_INST_APPEND = APP_USBD_EVT_FIRST_APP, /**< The instance was attached to the library, any configuration action can be done now */
+ APP_USBD_EVT_INST_REMOVE, /**<
+ * The instance is going to be removed, this event is called just before removing the instance.
+ * This removing cannot be stopped.
+ */
+ APP_USBD_EVT_STARTED, /**< USBD library has just been started and functional - event passed to all instances, before USBD interrupts have been enabled */
+ APP_USBD_EVT_STOPPED, /**< USBD library has just been stopped and is not functional - event passed to all instances, after USBD interrupts have been disabled*/
+
+ APP_USBD_EVT_STATE_CHANGED, /**<
+ * Informs all the classes that base state has been changed.
+ * This event is processed before setup stage that caused the state change finishes (before acknowledging it).
+ */
+
+ APP_USBD_EVT_FIRST_INTERNAL = 0x80, /**< First internal event, used by the APP library internally. */
+
+ APP_USBD_EVT_HFCLK_READY = APP_USBD_EVT_FIRST_INTERNAL, /**< High frequency clock started */
+ APP_USBD_EVT_START_REQ, /**< Start requested */
+ APP_USBD_EVT_STOP_REQ, /**< Stop requested */
+ APP_USBD_EVT_SUSPEND_REQ, /**< Suspend request - HFCLK would be released and USBD peripheral clock would be disconnected */
+ APP_USBD_EVT_WAKEUP_REQ, /**< Wakeup request - start the whole wakeup generation. */
+
+} app_usbd_event_type_t;
+
+
+
+/**
+ * @brief Specific application event structure
+ *
+ * All the data required by the events that comes from the application level
+ */
+typedef struct
+{
+ app_usbd_event_type_t type; //!< Event type
+} app_usbd_evt_t;
+
+/**
+ * @brief Specific application event structure with setup structure included
+ *
+ * This event structure would be used when @ref APP_USBD_EVT_DRV_SETUP
+ * is passed to instance event handler
+ */
+typedef struct
+{
+ app_usbd_event_type_t type; //!< Event type
+ app_usbd_setup_t setup; //!< Setup structure
+} app_usbd_setup_evt_t;
+
+
+/**
+ * @brief Complex event variable type
+ *
+ * A variable that can store any kind of event.
+ */
+typedef union
+{
+ app_usbd_event_type_t type; //!< Event type
+ nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver.
+ /**< Use this event structure only for event
+ * type < @ref APP_USBD_EVT_FIRST_APP
+ */
+ app_usbd_setup_evt_t setup_evt; //!< Event structure with SETUP structure included.
+ /**< This structure is used in connection with
+ * @ref APP_USBD_EVT_DRV_SETUP
+ */
+ app_usbd_evt_t app_evt; //!< Events that comes from the application driver.
+ /**< Use this event structure only for event
+ * type >= @ref APP_USBD_EVT_FIRST_APP
+ */
+} app_usbd_complex_evt_t;
+
+
+/**
+ * @brief Internal event variable type
+ *
+ * The variable type used for internal event processing.
+ * This kind of event is the one that goes into the event queue.
+ *
+ * @note There is no setup event structure.
+ * This structure would be created when setup event is processed.
+ * The reason for that is the fact that setup event structure has high memory printout.
+ */
+typedef union
+{
+ app_usbd_event_type_t type; //!< Event type
+ nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver.
+ /**< Use this event structure only for event
+ * type < @ref APP_USBD_EVT_FIRST_APP
+ */
+ app_usbd_evt_t app_evt; //!< Events that comes from the application driver.
+ /**< Use this event structure only for event
+ * type >= @ref APP_USBD_EVT_FIRST_APP
+ */
+} app_usbd_internal_evt_t;
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Base instance of a USBD class
+ *
+ * Any USBD class instance have to begin with this instance.
+ * This may then be followed by any implementation dependent data.
+ *
+ * For an instance it should be possible to put whole structure into FLASH.
+ *
+ * @note This type is early defined as incomplete type.
+ * This is required for function declaration that takes the pointer
+ * to this structure but in second hand - it is also placed inside
+ * the instance structure.
+ * @note The structure is defined in @file app_usbd_class_base.h.
+ */
+typedef struct {} app_usbd_class_inst_t;
+#else
+typedef struct app_usbd_class_inst_s app_usbd_class_inst_t;
+#endif
+/**
+ * @brief Endpoint callback function
+ *
+ * The function used by every class instance.
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] p_event Event to process
+ *
+ * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED
+ */
+typedef ret_code_t (*app_usbd_ep_event_handler_t)(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event
+ );
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c
new file mode 100644
index 0000000..19e5a36
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c
@@ -0,0 +1,813 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_AUDIO)
+
+#include "app_usbd_audio.h"
+#include "app_util_platform.h"
+
+/**
+ * @defgroup app_usbd_audio_internals USBD Audio internals
+ * @{
+ * @ingroup app_usbd_audio
+ * @internal
+ */
+
+STATIC_ASSERT(sizeof(app_usbd_audio_ac_iface_header_desc_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_audio_input_terminal_desc_t) == 12);
+STATIC_ASSERT(sizeof(app_usbd_audio_output_terminal_desc_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_audio_feature_unit_desc_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_iface_desc_t) == 7);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_one_desc_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_two_desc_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_three_desc_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_endpoint_desc_t) == 7);
+
+#define APP_USBD_AUDIO_CONTROL_IFACE_IDX 0 /**< Audio class control interface index */
+#define APP_USBD_AUDIO_STREAMING_IFACE_IDX 1 /**< Audio class streaming interface index */
+
+#define APP_USBD_CDC_AUDIO_STREAMING_EP_IDX 0 /**< Audio streaming isochronous endpoint index */
+
+/**
+ * @brief Auxiliary function to access audio class instance data
+ *
+ * @param[in] p_inst Class instance data
+ * @return Audio class instance data @ref app_usbd_audio_t
+ */
+static inline app_usbd_audio_t const * audio_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_audio_t const *)p_inst;
+}
+
+
+/**
+ * @brief Auxiliary function to access audio class context data
+ *
+ * @param[in] p_audio Audio class instance data
+ * @return Audio class context data @ref app_usbd_audio_ctx_t
+ */
+static inline app_usbd_audio_ctx_t * audio_ctx_get(app_usbd_audio_t const * p_audio)
+{
+ ASSERT(p_audio != NULL);
+ ASSERT(p_audio->specific.p_data != NULL);
+ return &p_audio->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event user Event type @ref app_usbd_audio_user_event_t
+ */
+static inline void user_event_handler(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_audio_user_event_t event)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ if (p_audio->specific.inst.user_ev_handler != NULL)
+ {
+ p_audio->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+
+/**
+ * @brief Select interface
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ * @param[in] alternate Alternate setting that should be selected
+ */
+static ret_code_t iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate)
+{
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ /* Simple check if this is data interface */
+ uint8_t const ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ if (ep_count > 0)
+ {
+ if (alternate > 1)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+ p_audio_ctx->streaming = (alternate != 0);
+
+ uint8_t i;
+
+ for (i = 0; i < ep_count; ++i)
+ {
+ nrf_drv_usbd_ep_t ep_addr =
+ app_usbd_class_ep_address_get(app_usbd_class_iface_ep_get(p_iface, i));
+ if (alternate)
+ {
+ app_usbd_ep_enable(ep_addr);
+ }
+ else
+ {
+ app_usbd_ep_disable(ep_addr);
+ }
+ }
+ return NRF_SUCCESS;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+static void iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+
+ /* Simple check if this is data interface */
+ if (p_iface->ep_cnt > 0)
+ {
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+ p_audio_ctx->streaming = false;
+ }
+ /* Note that all the interface endpoints would be disabled automatically after this function */
+}
+
+
+static uint8_t iface_selection_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ /* Simple check if this is data interface */
+ uint8_t const ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ if (ep_count > 0)
+ {
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+ return (p_audio_ctx->streaming) ? 1 : 0;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Internal SETUP standard IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by Audio class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP class IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_in(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_AUDIO_REQ_GET_CUR:
+ case APP_USBD_AUDIO_REQ_GET_MIN:
+ case APP_USBD_AUDIO_REQ_GET_MAX:
+ case APP_USBD_AUDIO_REQ_SET_RES:
+ case APP_USBD_AUDIO_REQ_GET_MEM:
+ {
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+
+
+ p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest;
+ p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb;
+ p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb;
+ p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb;
+ p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb;
+
+ p_audio_ctx->request.length = p_setup_ev->setup.wLength.w;
+
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_IN;
+
+ app_usbd_setup_reqrec_t rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType);
+ if (rec == APP_USBD_SETUP_REQREC_ENDPOINT)
+ {
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_IN;
+ }
+
+ user_event_handler((app_usbd_class_inst_t const *)p_audio,
+ APP_USBD_AUDIO_USER_EVT_CLASS_REQ);
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ p_audio_ctx->request.payload,
+ p_audio_ctx->request.length);
+ }
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+static ret_code_t audio_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status == NRF_USBD_EP_OK)
+ {
+ app_usbd_audio_t const * p_audio = p_context;
+
+ user_event_handler((app_usbd_class_inst_t const *)p_audio,
+ APP_USBD_AUDIO_USER_EVT_CLASS_REQ);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t audio_req_out(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+
+
+ p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest;
+ p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb;
+ p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb;
+ p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb;
+ p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb;
+
+ p_audio_ctx->request.length = p_setup_ev->setup.wLength.w;
+
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_OUT;
+ if (app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_ENDPOINT)
+ {
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_OUT;
+ }
+
+ /*Request setup data*/
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_audio_ctx->request.payload, p_audio_ctx->request.length);
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = audio_req_out_data_cb,
+ .p_context = (void *)p_audio
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief Internal SETUP class OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_out(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_AUDIO_REQ_SET_CUR:
+ case APP_USBD_AUDIO_REQ_SET_MIN:
+ case APP_USBD_AUDIO_REQ_SET_MAX:
+ case APP_USBD_AUDIO_REQ_SET_RES:
+ case APP_USBD_AUDIO_REQ_SET_MEM:
+ return audio_req_out(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Control endpoint handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_event_handler(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Endpoint IN event handler
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst)
+{
+ user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_TX_DONE);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Endpoint OUT event handler
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst)
+{
+ user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_RX_DONE);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Auxiliary function to access isochronous endpoint address
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return ISO endpoint address
+ */
+static inline nrf_drv_usbd_ep_t ep_iso_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_AUDIO_STREAMING_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_AUDIO_STREAMING_EP_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t audio_event_handler(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_RESET:
+ break;
+
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ ret = endpoint_in_event_handler(p_inst);
+ }
+ else
+ {
+ ret = endpoint_out_event_handler(p_inst);
+ }
+ break;
+
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+
+ case APP_USBD_EVT_STARTED:
+ break;
+
+ case APP_USBD_EVT_STOPPED:
+ break;
+
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+static size_t audio_get_format_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_format_dsc->size;
+}
+
+
+static size_t audio_get_format_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_format_dsc->p_data[cur_byte];
+}
+
+
+static size_t audio_get_input_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_input_dsc->size;
+}
+
+
+static size_t audio_get_input_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_input_dsc->p_data[cur_byte];
+}
+
+
+static size_t audio_get_output_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_output_dsc->size;
+}
+
+
+static size_t audio_get_output_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_output_dsc->p_data[cur_byte];
+}
+
+
+static size_t audio_get_feature_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_feature_dsc->size;
+}
+
+
+static size_t audio_get_feature_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_feature_dsc->p_data[cur_byte];
+}
+
+
+static uint8_t audio_get_control_interface_number(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * ifce = 0;
+
+ ifce = app_usbd_class_iface_get(p_inst, 0);
+ return app_usbd_class_iface_number_get(ifce);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::feed_descriptors
+ */
+
+static bool audio_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ ASSERT(ifaces == 2);
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* CONTROL INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL); // bInterfaceSubclass (Audio Control)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HEADER INTERFACE */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_INTERFACE); // bDescriptorType = Audio Interfaces
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER); // bDescriptorSubtype = Header
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(0x0100)); // bcdADC LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(0x0100)); // bcdADC MSB
+
+ static uint16_t header_desc_len = 0;
+ header_desc_len = 9 + audio_get_feature_descriptor_size(p_inst) +
+ audio_get_input_descriptor_size(p_inst) + audio_get_output_descriptor_size(
+ p_inst);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(header_desc_len)); // wTotalLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(header_desc_len)); // wTotalLength MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInCollection
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // baInterfaceNr(1)
+
+ /* INPUT TERMINAL DESCRIPTOR */
+ static uint32_t cur_byte = 0;
+ static size_t input_desc_size = 0;
+ input_desc_size = audio_get_input_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < input_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_input_descriptor_data(p_inst, cur_byte));
+ }
+
+ /* FEATURE UNIT DESCRIPTOR */
+ static size_t feature_desc_size = 0;
+ feature_desc_size = audio_get_feature_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < feature_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_feature_descriptor_data(p_inst, cur_byte));
+ }
+
+ /* OUTPUT TERMINAL DESCRIPTOR */
+ static size_t output_desc_size = 0;
+ output_desc_size = audio_get_output_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < output_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_output_descriptor_data(p_inst, cur_byte));
+ }
+
+ p_cur_iface++;
+
+ /* STREAM INTERFACE DESCRIPTOR ALT 0 */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.type_streaming); // bInterfaceSubclass (Audio Control)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* STREAM INTERFACE DESCRIPTOR ALT 1 */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.type_streaming); // bInterfaceSubclass (Audio Control)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* AudioStreaming GENERAL DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_INTERFACE); // bDescriptorType = Audio Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL); // bDescriptorSubtype = General
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bTerminalLink
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.delay); // bDelay
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_audio->specific.inst.format)); // wFormatTag LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_audio->specific.inst.format)); // wFormatTag MSB
+
+ /* FORMAT DESCRIPTOR */
+ static size_t format_desc_size = 0;
+ format_desc_size = audio_get_format_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < format_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_format_descriptor_data(p_inst, cur_byte));
+ }
+
+ /* ENDPOINT GENERAL DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT); // bDescriptorType = Audio Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_EP_SUBTYPE_GENERAL); // bDescriptorSubtype = EP General
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bLockDelayUnits
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(0x0000)); // wLockDelay LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(0x0000)); // wLockDelay MSB
+
+ /* ENDPOINT ISO DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, 0);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_audio->specific.inst.ep_size)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_audio->specific.inst.ep_size)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bRefresh
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bSynchAddress
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/** @} */
+
+const app_usbd_class_methods_t app_usbd_audio_class_methods = {
+ .event_handler = audio_event_handler,
+ .feed_descriptors = audio_feed_descriptors,
+ .iface_select = iface_select,
+ .iface_deselect = iface_deselect,
+ .iface_selection_get = iface_selection_get,
+};
+
+
+size_t app_usbd_audio_class_rx_size_get(app_usbd_class_inst_t const * p_inst)
+{
+ nrf_drv_usbd_ep_t ep_addr;
+
+ ep_addr = ep_iso_addr_get(p_inst);
+ ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
+
+ return (size_t)nrf_drv_usbd_epout_size_get(ep_addr);
+}
+
+
+ret_code_t app_usbd_audio_class_rx_start(
+ app_usbd_class_inst_t const * p_inst,
+ void * p_buff,
+ size_t size)
+{
+ nrf_drv_usbd_ep_t ep_addr;
+
+ ep_addr = ep_iso_addr_get(p_inst);
+ ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
+
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_buff, size);
+ return app_usbd_ep_transfer(ep_addr, &transfer);
+}
+
+
+ret_code_t app_usbd_audio_class_tx_start(
+ app_usbd_class_inst_t const * p_inst,
+ const void * p_buff,
+ size_t size)
+{
+ nrf_drv_usbd_ep_t ep_addr;
+
+ ep_addr = ep_iso_addr_get(p_inst);
+ ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
+
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_buff, size);
+ return app_usbd_ep_transfer(ep_addr, &transfer);
+}
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_AUDIO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h
new file mode 100644
index 0000000..f094bbb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h
@@ -0,0 +1,329 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_AUDIO_H__
+#define APP_USBD_AUDIO_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_audio_types.h"
+#include "app_usbd_audio_desc.h"
+#include "app_usbd_audio_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio USB AUDIO class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by USB Audio class.
+ *
+ * @details Reference specifications:
+ * - "Universal Serial Bus Device Class Definition for Audio Devices"
+ * Release 1.0, March 18, 1998.
+ * - "Universal Serial Bus Device Class Definition for Audio Data Formats"
+ * Release 1.0, March 18, 1998.
+ * - "Universal Serial Bus Device Class Definition for Terminal Types"
+ * Release 1.0, March 18, 1998.
+ *
+ * @{
+ */
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Audio class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_audio_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_audio, \
+ APP_USBD_AUDIO_CONFIG(0, 1), \
+ APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_AUDIO_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler
+ *
+ * @note Example prototype of user event handler:
+ *
+ * @code
+ void audio_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_audio_user_event_t event);
+ * @endcode
+ */
+typedef enum app_usbd_audio_user_event_e {
+ APP_USBD_AUDIO_USER_EVT_CLASS_REQ, /**< User event CLASS_REQ */
+ APP_USBD_AUDIO_USER_EVT_RX_DONE, /**< User event RX_DONE */
+ APP_USBD_AUDIO_USER_EVT_TX_DONE, /**< User event TX_DONE */
+} app_usbd_audio_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Global definition of app_usbd_audio_t class instance
+ *
+ * @param instance_name Name of global instance
+ * @param interfaces_configs Interfaces configurations
+ * @param user_ev_handler User event handler
+ * @param format_descriptor Audio class Format descriptor
+ * @param input_descriptor Audio class Input Terminal descriptor
+ * @param output_descriptor Audio class Output Terminal descriptor
+ * @param feature_descriptor Audio class Feature Unit descriptor
+ * @param delay Streaming delay
+ * @param format FormatTag (@ref app_usbd_audio_as_iface_format_tag_t)
+ * @param ep_size Endpoint size
+ * @param type_str Streaming type MIDISTREAMING/AUDIOSTREAMING
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL
+ *
+ */
+#define APP_USBD_AUDIO_GLOBAL_DEF(instance_name, \
+ interfaces_configs, \
+ user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str) \
+ APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \
+ interfaces_configs, \
+ user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str)
+
+
+/**
+ * @brief Initializer of Audio Format descriptor
+ *
+ * @param name Format descriptor name
+ * @param ... Format descriptor data
+*/
+
+#define APP_USBD_AUDIO_FORMAT_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of Audio Input descriptor
+ *
+ * @param name Input descriptor name
+ * @param ... Input descriptor data
+*/
+
+#define APP_USBD_AUDIO_INPUT_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of Audio Output descriptor
+ *
+ * @param name Output descriptor name
+ * @param ... Output descriptor data
+*/
+
+#define APP_USBD_AUDIO_OUTPUT_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of Feture Output descriptor
+ *
+ * @param name Feture descriptor name
+ * @param ... Feture descriptor data
+*/
+
+#define APP_USBD_AUDIO_FEATURE_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @@brief Helper function to get class instance from Audio class
+ *
+ * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF)
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_audio_class_inst_get(app_usbd_audio_t const * p_audio)
+{
+ return &p_audio->base;
+}
+
+/**
+ * @brief Helper function to get audio specific request from audio class
+ *
+ * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF)
+ * @return Audio class specific request
+ */
+static inline app_usbd_audio_req_t *
+app_usbd_audio_class_request_get(app_usbd_audio_t const * p_audio)
+{
+ return &p_audio->specific.p_data->ctx.request;
+}
+
+/**
+ * @brief Helper function to get audio from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ * @return Audio class handle
+ */
+static inline app_usbd_audio_t const *
+app_usbd_audio_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_audio_t const *)p_inst;
+}
+
+/**
+ * @brief Get the size of last received transfer.
+ *
+ * @note Call this function in reaction to a SOF event to check if there is any data to process.
+ *
+ * @param p_inst Base class instance.
+ *
+ * @return Number of bytes received in the last transmission.
+ */
+size_t app_usbd_audio_class_rx_size_get(app_usbd_class_inst_t const * p_inst);
+
+/**
+ * @brief Start audio data copying from the endpoint buffer.
+ *
+ * Function to be used to copy data from an audio OUT endpoint to a given buffer.
+ * When it finishes, an @ref APP_USBD_AUDIO_USER_EVT_RX_DONE event is generated.
+ *
+ * @param p_inst Base class instance.
+ * @param p_buff Target buffer.
+ * @param size Size of the requested data.
+ *
+ * @return Result of the endpoint transmission start.
+ *
+ * @sa app_usbd_audio_class_rx_size_get
+ *
+ * @note This function should be called in reaction to a SOF event.
+ * Isochronous endpoints are double buffered and they are automatically switched at every SOF.
+ */
+ret_code_t app_usbd_audio_class_rx_start(
+ app_usbd_class_inst_t const * p_inst,
+ void * p_buff,
+ size_t size);
+
+/**
+ * @brief Start copying audio data to the endpoint buffer.
+ *
+ * Function to be used to copy data to an audio IN endpoint from a given buffer.
+ * When it finishes, an @ref APP_USBD_AUDIO_USER_EVT_TX_DONE event is generated.
+ *
+ * @param p_inst Base class instance.
+ * @param p_buff Source buffer.
+ * @param size Size of the data to be sent.
+ *
+ * @return Result of the endpoint transsmision start.
+ *
+ * @note This function should be called in reaction to a SOF event.
+ * Isochronous endpoints are double buffered and they are automatically switched at every SOF.
+ */
+ret_code_t app_usbd_audio_class_tx_start(
+ app_usbd_class_inst_t const * p_inst,
+ const void * p_buff,
+ size_t size);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h
new file mode 100644
index 0000000..dbc4d41
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h
@@ -0,0 +1,318 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_AUDIO_DESC_H__
+#define APP_USBD_AUDIO_DESC_H__
+
+#include "app_usbd_descriptor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio_dsc USB Audio descriptors
+ * @brief @tagAPI52840 Descriptors used in the USB Audio class.
+ * @ingroup app_usbd_audio
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for AUDIO class
+ *
+ * @param interface_number Interface number
+ * @param alt_setting Interface alternate setting
+ * @param ep_num Number of endpoints
+ * @param subclass Audio subclass @ref app_usbd_audio_subclass_t
+ * */
+#define APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, subclass) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ (interface_number), \
+ /*.bAlternateSetting = */ (alt_setting), \
+ /*.bNumEndpoints = */ (ep_num), \
+ /*.bInterfaceClass = */ APP_USBD_AUDIO_CLASS, \
+ /*.bInterfaceSubClass = */ (subclass), \
+ /*.bInterfaceProtocol = */ APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED, \
+ /*.iInterface = 0, */ 0x00, \
+
+/**
+ * @brief Initializer of isochronous endpoint descriptors for audio class
+ *
+ * @param ep ISO endpoint id: @ref NRF_DRV_USBD_EPIN8, @ref NRF_DRV_USBD_EPOUT8
+ * @param ep_size Endpoint size (bytes)
+ * @param interval Endpoint interval (milliseconds)
+ * @param refresh Refresh value (usually 0)
+ * @param synch_addr Synch address (usually 0)
+ * */
+#define APP_USBD_AUDIO_ISO_EP_DSC(ep, ep_size, interval, refresh, synch_addr) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t) + 2, \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ ep, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ (interval), \
+ /*.bRefresh = */ (refresh), \
+ /*.bInterval = */ (synch_addr), \
+
+/**
+ * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO IN endpoint
+ */
+#define APP_USBD_AUDIO_ISO_EP_IN_DSC(ep_size) \
+ APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPIN8, ep_size, 1, 0, 0)
+
+/**
+ * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO OUT endpoint
+ */
+#define APP_USBD_AUDIO_ISO_EP_OUT_DSC(ep_size) \
+ APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPOUT8, ep_size, 1, 0, 0)
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_ac_iface_header_desc_t
+ *
+ * @param descriptor_list Descriptor list following audio interface header descriptor
+ * @param ... List of interfaces following audio control interface
+ * */
+#define APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_ac_iface_header_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, \
+ /*.bcdADC = */ APP_USBD_U16_TO_RAW_DSC(0x0100), \
+ /*.wTotalLength = */ APP_USBD_U16_TO_RAW_DSC( \
+ sizeof((uint8_t[]){BRACKET_EXTRACT(descriptor_list)}) + \
+ sizeof(app_usbd_audio_ac_iface_header_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__))), \
+ /*.bInCollection = */ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.baInterfaceNr[] = */ __VA_ARGS__, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_input_terminal_desc_t
+ *
+ * @param terminal_id Terminal ID
+ * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t
+ * @param nr_channels Number of channels
+ * @param ch_config CHannel config bitmask
+ * */
+#define APP_USBD_AUDIO_INPUT_TERMINAL_DSC(terminal_id, terminal_type, nr_channels, ch_config) \
+ /*.bLength = */ sizeof(app_usbd_audio_input_terminal_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, \
+ /*.bTerminalID = */ (terminal_id), \
+ /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \
+ /*.bAssocTerminal = */ 0, \
+ /*.bNrChannels = */ (nr_channels), \
+ /*.wChannelConfig = */ APP_USBD_U16_TO_RAW_DSC(ch_config), \
+ /*.iChannelNames = */ 0, \
+ /*.iTerminal = */ 0, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_output_terminal_desc_t
+ *
+ * @param terminal_id Terminal ID
+ * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t
+ * @param source_id Source ID
+ * */
+#define APP_USBD_AUDIO_OUTPUT_TERMINAL_DSC(terminal_id, terminal_type, source_id) \
+ /*.bLength = */ sizeof(app_usbd_audio_output_terminal_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, \
+ /*.bTerminalID = */ (terminal_id), \
+ /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \
+ /*.bAssocTerminal = */ 0, \
+ /*.bSourceID = */ (source_id), \
+ /*.iTerminal = */ 0, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_feature_unit_desc_t
+ *
+ * @param unit_id Unit ID
+ * @param source_id Source ID
+ * @param ... List of controls
+ * */
+#define APP_USBD_AUDIO_FEATURE_UNIT_DSC(unit_id, source_id, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_feature_unit_desc_t) + \
+ 1 + (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, \
+ /*.bUnitID = */ (unit_id), \
+ /*.bSourceID = */ (source_id), \
+ /*.bControlSize = */ sizeof(uint16_t), \
+ /*.bmaControls[] = */ __VA_ARGS__, \
+ /*.iFeature = */ 0, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_iface_desc_t
+ *
+ * @param terminal_link Terminal link
+ * @param delay Delay
+ * @param format_tag Format TAG
+ * */
+#define APP_USBD_AUDIO_AS_IFACE_DSC(terminal_link, delay, format_tag) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_iface_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, \
+ /*.bTerminalLink = */ (terminal_link), \
+ /*.bDelay = */ (delay), \
+ /*.wFormatTag = */ APP_USBD_U16_TO_RAW_DSC(format_tag), \
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_format_type_one_desc_t
+ *
+ * @param nr_channels Number of channels
+ * @param subframe_size Subframe size
+ * @param resolution Bit resolution
+ * @param freq_type Frequency type
+ * @param ... List of frequencies
+ * */
+#define APP_USBD_AUDIO_AS_FORMAT_I_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_format_type_one_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ /*.bFormatType = */ (1), \
+ /*.bNrChannels = */ (nr_channels), \
+ /*.bSubframeSize = */ (subframe_size), \
+ /*.bBitResolution = */ (resolution), \
+ /*.bSamFreqType = */ (freq_type), \
+ /*.tSamFreq = */ __VA_ARGS__, \
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_format_type_two_desc_t
+ *
+ * @param max_bitrate Maximum bitrate
+ * @param samples_per_frame Samples per frame
+ * @param freq_type Frequency type
+ * @param ... List of frequencies
+ * */
+#define APP_USBD_AUDIO_AS_FORMAT_II_DSC(max_bitrate, samples_per_frame, freq_type, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_format_type_two_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ /*.bFormatType = */ (2), \
+ /*.wMaxBitRate = */ APP_USBD_U16_TO_RAW_DSC(max_bitrate), \
+ /*.wSamplesPerFrame = */ APP_USBD_U16_TO_RAW_DSC(samples_per_frame), \
+ /*.bSamFreqType = */ (freq_type), \
+ /*.tSamFreq = */ __VA_ARGS__, \
+
+/**
+* @brief Initializer of @ref app_usbd_audio_as_format_type_three_desc_t
+ *
+ * @param nr_channels Number of channels
+ * @param subframe_size Subframe size
+ * @param resolution Bit resolution
+ * @param freq_type Frequency type
+ * @param ... List of frequencies
+ * */
+#define APP_USBD_AUDIO_AS_FORMAT_III_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_format_type_three_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ /*.bFormatType = */ (3), \
+ /*.bNrChannels = */ (nr_channels), \
+ /*.bSubframeSize = */ (subframe_size), \
+ /*.bBitResolution = */ (resolution), \
+ /*.bSamFreqType = */ (freq_type), \
+ /*.tSamFreq = */ __VA_ARGS__, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_endpoint_desc_t
+ *
+ * @param attributes Endpoint attributes
+ * @param lock_delay_units Lock delay units
+ * @param lock_delay Lock delay
+ * */
+#define APP_USBD_AUDIO_EP_GENERAL_DSC(attributes, lock_delay_units, lock_delay) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_endpoint_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, \
+ /*.bmAttributes = */ (attributes), \
+ /*.bLockDelayUnits = */ (lock_delay_units), \
+ /*.wLockDelay = */ APP_USBD_U16_TO_RAW_DSC(lock_delay), \
+
+/**
+ * @brief Macro to configure Audio Class control descriptor
+ *
+ * @param interface_number Interface number
+ * @param descriptor_list List of descriptors after Audio interface header descriptor
+ * @param interface_list List of interfaces passed to @ref APP_USBD_AUDIO_AC_IFACE_HEADER_DSC
+ * */
+#define APP_USBD_AUDIO_CONTROL_DSC(interface_number, descriptor_list, interface_list) \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, 0, 0, APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \
+ APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, BRACKET_EXTRACT(interface_list)) \
+ BRACKET_EXTRACT(descriptor_list)
+
+
+/**
+ * @brief Macro to configure Audio Class streaming descriptor
+ *
+ * @param interface_number Interface number
+ * @param alt_setting Alternate interface setting
+ * @param ep_num Number of endpoints
+ */
+#define APP_USBD_AUDIO_STREAMING_DSC(interface_number, alt_setting, ep_num) \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \
+ APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING)
+
+/**
+ * @brief Macro to configure Audio Class MIDI streaming descriptor
+ *
+ * @param interface_number Interface number
+ * @param alt_setting Alternate interface setting
+ * @param ep_num Number of endpoints
+ */
+#define APP_USBD_AUDIO_MIDI_STREAMING_DSC(interface_number, alt_setting, ep_num) \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \
+ APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING)
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h
new file mode 100644
index 0000000..c3371b2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h
@@ -0,0 +1,284 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_AUDIO_INTERNAL_H__
+#define APP_USBD_AUDIO_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio_internal USB Audio internals
+ * @brief @tagAPI52840 USB Audio class internals.
+ * @ingroup app_usbd_audio
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in audio class
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_audio);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_audio_user_event_e
+ *
+ */
+enum app_usbd_audio_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event User event
+ *
+ */
+typedef void (*app_usbd_audio_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_audio_user_event_e event);
+
+
+/**
+* @brief Audio subclass descriptor.
+*/
+
+typedef struct {
+ size_t size;
+ uint8_t type;
+ uint8_t const * const p_data;
+} app_usbd_audio_subclass_desc_t;
+
+/**
+ * @brief Audio class part of class instance data
+ */
+typedef struct {
+
+ app_usbd_audio_subclass_desc_t const * const p_format_dsc; //!< Audio class Format descriptor
+ app_usbd_audio_subclass_desc_t const * const p_input_dsc; //!< Audio class Input Terminal descriptor
+ app_usbd_audio_subclass_desc_t const * const p_output_dsc; //!< Audio class Output Terminal descriptor
+ app_usbd_audio_subclass_desc_t const * const p_feature_dsc; //!< Audio class Feature Unit descriptor
+
+ uint8_t delay; //!< Streaming delay
+ uint16_t format; //!< FormatTag (@ref app_usbd_audio_as_iface_format_tag_t)
+ uint16_t ep_size; //!< Endpoint size
+
+ app_usbd_audio_subclass_t type_streaming; //Streaming type MIDISTREAMING/AUDIOSTREAMING (@ref app_usbd_audio_subclass_t)
+
+ app_usbd_audio_user_ev_handler_t user_ev_handler; //!< User event handler
+} app_usbd_audio_inst_t;
+
+/**
+ * @brief Audio class request target
+ */
+typedef enum {
+ APP_USBD_AUDIO_CLASS_REQ_IN, /**< Audio class request IN */
+ APP_USBD_AUDIO_CLASS_REQ_OUT, /**< Audio class request OUT */
+ APP_USBD_AUDIO_EP_REQ_IN, /**< Audio class endpoint request IN */
+ APP_USBD_AUDIO_EP_REQ_OUT, /**< Audio class endpoint request OUT */
+} app_usbd_audio_class_req_target_t;
+
+/**
+ * @brief Audio class specific request handled via control endpoint
+ */
+typedef struct {
+ app_usbd_audio_class_req_target_t req_target; //!< Request target
+ app_usbd_audio_req_type_t req_type; //!< Request type
+
+ uint8_t control; //!< Request control field
+ uint8_t channel; //!< Channel ID
+ uint8_t interface; //!< Interface ID
+ uint8_t entity; //!< Entity ID
+ uint16_t length; //!< Request payload length
+
+ uint8_t payload[64]; //!< Request payload
+} app_usbd_audio_req_t;
+
+
+/**
+ * @brief Audio class context
+ *
+ */
+typedef struct {
+ app_usbd_audio_req_t request; //!< Audio class request
+ bool streaming; //!< Streaming flag
+} app_usbd_audio_ctx_t;
+
+
+/**
+ * @brief Audio class configuration macro
+ *
+ * Used by @ref APP_USBD_AUDIO_GLOBAL_DEF
+ *
+ * @param iface_control Interface number of audio control
+ * @param iface_stream Interface number of audio stream
+ */
+#define APP_USBD_AUDIO_CONFIG(iface_control, iface_stream) \
+ ((iface_control), \
+ (iface_stream, 0))
+
+/**
+ * @brief Only IN audio stream configuration
+ *
+ * @param iface_control Interface number of audio control
+ * @param iface_stream_in Interface number of audio stream on IN endpoint
+ */
+#define APP_USBD_AUDIO_CONFIG_IN(iface_control, iface_stream_in) \
+ ((iface_control), (iface_stream_in, NRF_DRV_USBD_EPIN8))
+
+
+/**
+ * @brief Only OUT audio stream configuration
+ *
+ * @param iface_control Interface number of audio control
+ * @param iface_stream_out Interface number of audio stream on OUT endpoint
+ */
+#define APP_USBD_AUDIO_CONFIG_OUT(iface_control, iface_stream_out) \
+ ((iface_control), (iface_stream_out, NRF_DRV_USBD_EPOUT8))
+
+/**
+ * @brief Specific class constant data for audio class
+ *
+ * @ref app_usbd_audio_inst_t
+ */
+#define APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC app_usbd_audio_inst_t inst;
+
+/**
+ * @brief Configures audio class instance
+ *
+ * @param user_event_handler User event handler
+ * @param format_descriptor Audio class Format descriptor
+ * @param input_descriptor Audio class Input Terminal descriptor
+ * @param output_descriptor Audio class Output Terminal descriptor
+ * @param feature_descriptor Audio class Feature Unit descriptor
+ * @param dlay Streaming delay
+ * @param frmat FormatTag (@ref app_usbd_audio_as_iface_format_tag_t)
+ * @param ep_siz Endpoint size
+ * @param type_str Streaming type MIDISTREAMING/AUDIOSTREAMING
+ */
+ #define APP_USBD_AUDIO_INST_CONFIG(user_event_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ dlay, \
+ frmat, \
+ ep_siz, \
+ type_str) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .p_format_dsc = format_descriptor, \
+ .p_input_dsc = input_descriptor, \
+ .p_output_dsc = output_descriptor, \
+ .p_feature_dsc = feature_descriptor, \
+ .delay = dlay, \
+ .format = frmat, \
+ .ep_size = ep_siz, \
+ .type_streaming = type_str \
+ }
+
+/**
+ * @brief Specific class data for audio class
+ *
+ * @ref app_usbd_audio_ctx_t
+ */
+#define APP_USBD_AUDIO_DATA_SPECIFIC_DEC app_usbd_audio_ctx_t ctx;
+
+
+/**
+ * @brief Audio class descriptors config macro
+ *
+ * @param interface_number Interface number
+ * @param ... Extracted endpoint list
+ */
+#define APP_USBD_AUDIO_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, \
+ 0, \
+ 0, \
+ APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \
+ }
+
+/**
+ * @brief Public audio class interface
+ *
+ */
+extern const app_usbd_class_methods_t app_usbd_audio_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_audio_t class
+ *
+ */
+ #define APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \
+ interfaces_configs, \
+ user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str) \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_audio, \
+ &app_usbd_audio_class_methods, \
+ interfaces_configs, \
+ (APP_USBD_AUDIO_INST_CONFIG(user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h
new file mode 100644
index 0000000..57fd902
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h
@@ -0,0 +1,382 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_AUDIO_TYPES_H__
+#define APP_USBD_AUDIO_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio_types USB Audio types
+ * @brief @tagAPI52840 Type definitions for the USB Audio class.
+ * @ingroup app_usbd_audio
+ * @{
+ */
+
+/** @brief Audio class definition in interface descriptor
+ *
+ * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_AUDIO_CLASS 0x01
+
+/** @brief Audio class protocol definition in interface descriptor
+ *
+ * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ * */
+#define APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED 0x00
+
+/**
+ * @brief Audio subclass possible values
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ */
+typedef enum {
+ APP_USBD_AUDIO_SUBCLASS_UNDEFINED = 0x00, /**< UNDEFINED subclass */
+ APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL, /**< AUDIOCONTROL subclass */
+ APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING, /**< AUDIOSTREAMING subclass */
+ APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING /**< MIDISTREAMING subclass */
+} app_usbd_audio_subclass_t;
+
+
+/**
+ * @brief Audio class specific descriptor types
+ */
+typedef enum {
+ APP_USBD_AUDIO_DESCRIPTOR_UNDEFINED = 0x20, /**< UNDEFINED descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_DEVICE = 0x21, /**< DEVICE descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_CONFIGURATION = 0x22, /**< CONFIGURATION descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_STRING = 0x23, /**< STRING descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE = 0x24, /**< INTERFACE descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT = 0x25, /**< ENDPOINT descriptor type */
+} app_usbd_audio_descriptor_type_t;
+
+
+/**
+ * @brief Audio control interface subtype
+ */
+typedef enum {
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio control interface subtype UNDEFINED */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, /**< Audio control interface subtype HEADER */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, /**< Audio control interface subtype INPUT_TERMINAL */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, /**< Audio control interface subtype OUTPUT_TERNINAL */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_MIXER_UNIT, /**< Audio control interface subtype MIXER_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_SELECTOR_UNIT, /**< Audio control interface subtype SELECTOR_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, /**< Audio control interface subtype FEATURE_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_PROCESSING_UNIT, /**< Audio control interface subtype PROCESSING_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_EXTENSION_UNIT, /**< Audio control interface subtype EXTENSION_UNIT */
+} app_usbd_audio_ac_iface_subtype_t;
+
+/**
+ * @brief Audio streaming interface subtype
+ */
+typedef enum {
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio streaming interface subtype UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, /**< Audio streaming interface subtype GENERAL */
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, /**< Audio streaming interface subtype FORMAT_TYPE */
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_SPECIFIC, /**< Audio streaming interface subtype FORMAT_SPECIFIC*/
+} app_usbd_audio_as_iface_subtype_t;
+
+
+/**
+ * @brief Audio class specific endpoint subtypes
+ */
+typedef enum {
+ APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED = 0x00, /**< APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED */
+ APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, /**< APP_USBD_AUDIO_EP_SUBTYPE_GENERAL */
+} app_usbd_audio_ep_subtype_t;
+
+/**
+ * @brief Audio class specific requests
+ *
+ * @ref nrf_drv_usbd_setup_t::bmRequestType
+ */
+typedef enum {
+ APP_USBD_AUDIO_REQ_UNDEFINED = 0x00, /**< UNDEFINED request*/
+
+ APP_USBD_AUDIO_REQ_SET_CUR = 0x01, /**< SET_CUR request */
+ APP_USBD_AUDIO_REQ_SET_MIN = 0x02, /**< SET_MIN request */
+ APP_USBD_AUDIO_REQ_SET_MAX = 0x03, /**< SET_MAX request */
+ APP_USBD_AUDIO_REQ_SET_RES = 0x04, /**< SET_RES request */
+ APP_USBD_AUDIO_REQ_SET_MEM = 0x05, /**< SET_MEM request */
+
+ APP_USBD_AUDIO_REQ_GET_CUR = 0x81, /**< GET_CUR request */
+ APP_USBD_AUDIO_REQ_GET_MIN = 0x82, /**< GET_MIN request */
+ APP_USBD_AUDIO_REQ_GET_MAX = 0x83, /**< GET_MAX request */
+ APP_USBD_AUDIO_REQ_GET_RES = 0x84, /**< GET_RES request */
+ APP_USBD_AUDIO_REQ_GET_MEM = 0x85, /**< GET_MEM request */
+
+ APP_USBD_AUDIO_REQ_GET_STAT = 0xFF, /**< GET_STAT request */
+} app_usbd_audio_req_type_t;
+
+/**
+ * @brief Audio class terminal types
+ * */
+typedef enum {
+ /*USB terminals*/
+ APP_USBD_AUDIO_TERMINAL_USB_UNDEFINED = 0x0100, /**< USB_UNDEFINED*/
+ APP_USBD_AUDIO_TERMINAL_USB_STREAMING = 0x0101, /**< USB_STREAMING */
+ APP_USBD_AUDIO_TERMINAL_USB_VENDOR_SPEC = 0x01FF, /**< USB_VENDOR_SPEC*/
+
+ /*Input terminals*/
+ APP_USBD_AUDIO_TERMINAL_IN_UNDEFINED = 0x0200, /**< UNDEFINED */
+ APP_USBD_AUDIO_TERMINAL_IN_MICROPHONE = 0x0201, /**< MICROPHONE */
+ APP_USBD_AUDIO_TERMINAL_IN_DESKTOP_MIC = 0x0202, /**< DESKTOP_MIC */
+ APP_USBD_AUDIO_TERMINAL_IN_PERSONAL_MIC = 0x0203, /**< PERSONAL_MIC */
+ APP_USBD_AUDIO_TERMINAL_IN_OM_DIR_MIC = 0x0204, /**< OM_DIR_MIC */
+ APP_USBD_AUDIO_TERMINAL_IN_MIC_ARRAY = 0x0205, /**< MIC_ARRAY */
+ APP_USBD_AUDIO_TERMINAL_IN_PROC_MIC_ARRAY = 0x0205, /**< PROC_MIC_ARRAY */
+
+ /*Output terminals*/
+ APP_USBD_AUDIO_TERMINAL_OUT_UNDEFINED = 0x0300, /**< UNDEFINED */
+ APP_USBD_AUDIO_TERMINAL_OUT_SPEAKER = 0x0301, /**< SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_HEADPHONES = 0x0302, /**< HEADPHONES */
+ APP_USBD_AUDIO_TERMINAL_OUT_HEAD_AUDIO = 0x0303, /**< HEAD_AUDIO */
+ APP_USBD_AUDIO_TERMINAL_OUT_DESKTOP_SPEAKER = 0x0304, /**< DESKTOP_SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_ROOM_SPEAKER = 0x0305, /**< ROOM_SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_COMM_SPEAKER = 0x0306, /**< COMM_SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_LOW_FREQ_SPEAKER = 0x0307, /**< LOW_FREQ_SPEAKER */
+
+ /*Input/Output terminals*/
+ APP_USBD_AUDIO_TERMINAL_IO_UNDEFINED = 0x0400, /**< UNDEFINED */
+ APP_USBD_AUDIO_TERMINAL_IO_HANDSET = 0x0401, /**< HANDSET */
+ APP_USBD_AUDIO_TERMINAL_IO_HEADSET = 0x0402, /**< HEADSET */
+ APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_NONE = 0x0403, /**< SPEAKERPHONE_ECHO_NONE */
+ APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_SUP = 0x0404, /**< SPEAKERPHONE_ECHO_SUP */
+ APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_CAN = 0x0405, /**< SPEAKERPHONE_ECHO_CAN */
+} app_usbd_audio_terminal_type_t;
+
+/**
+ * @brief Audio class control interface header descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER
+ uint8_t bcdADC[2]; //!< BCD ADC
+ uint8_t wTotalLength[2]; //!< Total interfaces length
+ uint8_t bInCollection; //!< Input collection
+ uint8_t baInterfaceNr[]; //!< Interface number list
+} app_usbd_audio_ac_iface_header_desc_t;
+
+
+/**
+ * @brief Possible values of input terminal channel config
+ *
+ * @ref app_usbd_audio_input_terminal_desc_t::wChannelConfig
+ * */
+typedef enum {
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_FRONT = (1u << 0), /**< Channel config bit LEFT_FRONT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_FRONT = (1u << 1), /**< Channel config bit RIGHT_FRONT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_CENTER_FRONT = (1u << 2), /**< Channel config bit CENTER_FRONT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LOW_FREQ_ENH = (1u << 3), /**< Channel config bit LOW_FREQ_ENH */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_SURROUND = (1u << 4), /**< Channel config bit LEFT_SURROUND */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_SURROUND = (1u << 5), /**< Channel config bit RIGHT_SURROUND */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_OF_CENTER = (1u << 6), /**< Channel config bit LEFT_OF_CENTER */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_OF_CENTER = (1u << 7), /**< Channel config bit RIGHT_OF_CENTER */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SURROUND = (1u << 8), /**< Channel config bit SURROUND */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_LEFT = (1u << 9), /**< Channel config bit SIDE_LEFT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_RIGHT = (1u << 10), /**< Channel config bit SIDE_RIGHT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_TOP = (1u << 11), /**< Channel config bit TOP */
+} app_usbd_audio_in_term_ch_config_t;
+
+/**
+ * @brief Audio class input terminal descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL
+ uint8_t bTerminalID; //!< Terminal ID
+ uint8_t wTerminalType[2]; //!< Terminal type
+ uint8_t bAssocTerminal; //!< Association terminal
+ uint8_t bNrChannels; //!< Number of channels
+ uint8_t wChannelConfig[2]; //!< Channel config
+ uint8_t iChannelNames; //!< Channel names
+ uint8_t iTerminal; //!< Terminal string ID
+} app_usbd_audio_input_terminal_desc_t;
+
+/**
+ * @brief Audio class output terminal descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL
+ uint8_t bTerminalID; //!< Terminal ID
+ uint8_t wTerminalType[2]; //!< Terminal type
+ uint8_t bAssocTerminal; //!< Association terminal
+ uint8_t bSourceID; //!< Source ID
+ uint8_t iTerminal; //!< Terminal string ID
+} app_usbd_audio_output_terminal_desc_t;
+
+/**
+ * @brief Possible values of feature unit control field*/
+typedef enum {
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE = (1u << 0), /**< Feature unit control bit MUTE */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_VOLUME = (1u << 1), /**< Feature unit control bit VOLUME */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS = (1u << 2), /**< Feature unit control bit BASS */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MID = (1u << 3), /**< Feature unit control bit MID */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_TREBLE = (1u << 4), /**< Feature unit control bit TREBLE */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_GRAPH_EQ = (1u << 5), /**< Feature unit control bit GRAPH_EQ */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_AUTO_GAIN = (1u << 6), /**< Feature unit control bit AUTO_GAIN */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_DELAY = (1u << 7), /**< Feature unit control bit DELAY */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS_BOOST = (1u << 8), /**< Feature unit control bit BASS_BOOST*/
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_LOUDNESS = (1u << 9), /**< Feature unit control bit LOUDNESS */
+} app_usbd_audio_feature_unit_control_t;
+
+/**
+ * @brief Audio class feature unit descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT
+ uint8_t bUnitID; //!< Unit ID
+ uint8_t bSourceID; //!< Source ID
+ uint8_t bControlSize; //!< Control size
+ uint8_t bmaControls[]; //!< Controls array
+} app_usbd_audio_feature_unit_desc_t;
+
+/**
+ * @brief Format tag in audio streaming interface descriptor
+ *
+ * @ref app_usbd_audio_as_iface_desc_t::wFormatTag
+ * */
+typedef enum {
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_I_UNDEFINED = 0x0000, /**< AS format TYPE_I_UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM = 0x0001, /**< AS format PCM */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM8 = 0x0002, /**< AS format PCM8 */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEEE_FLOAT = 0x0003, /**< AS format IEEE_FLOAT */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_ALAW = 0x0004, /**< AS format ALAW */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_MULAW = 0x0005, /**< AS format MULAW */
+
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_II_UNDEFINED = 0x1000, /**< AS format TYPE_II_UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_MPEG = 0x1001, /**< AS format MPEG */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_AC3 = 0x1002, /**< AS format AC3 */
+
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_III_UNDEFINED = 0x2000, /**< AS format TYPE_III_UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_AC_3 = 0x2001, /**< AS format IEC1937_AC_3 */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_1_LAYER1 = 0x2002, /**< AS format IEC1937_MPEG_1_LAYER1 */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_NOEXT = 0x2003, /**< AS format IEC1937_MPEG_2_NOEXT */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_EXT = 0x2004, /**< AS format IEC1937_MPEG_2_EXT */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER1_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER1_LS */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER23_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER23_LS */
+} app_usbd_audio_as_iface_format_tag_t;
+
+/**
+ * @brief Audio class audio streaming interface descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_ac_iface_subtype_t
+ uint8_t bTerminalLink; //!< Terminal link
+ uint8_t bDelay; //!< Delay
+ uint8_t wFormatTag[2]; //!< Format TAG
+} app_usbd_audio_as_iface_desc_t;
+
+/**
+ * @brief Audio class audio streaming format type I descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t
+ uint8_t bFormatType; //!< Format type: fixed value 1
+ uint8_t bNrChannels; //!< Number of channels
+ uint8_t bSubframeSize; //!< Subframe size
+ uint8_t bBitResolution; //!< Bit resolution
+ uint8_t bSamFreqType; //!< Number of supported sampling frequencies
+ uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries)
+} app_usbd_audio_as_format_type_one_desc_t;
+
+
+/**
+ * @brief Audio class audio streaming format type II descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t
+ uint8_t bFormatType; //!< Format type: fixed value 2
+ uint8_t wMaxBitRate[2]; //!< Maximum bitrate
+ uint8_t wSamplesPerFrame[2]; //!< Samples per frame
+ uint8_t bSamFreqType; //!< Number of supported sampling frequencies
+ uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries)
+} app_usbd_audio_as_format_type_two_desc_t;
+
+/**
+ * @brief Audio class audio streaming format type III descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t
+ uint8_t bFormatType; //!< Format type: fixed value 1
+ uint8_t bNrChannels; //!< Number of channels
+ uint8_t bSubframeSize; //!< Subframe size
+ uint8_t bBitResolution; //!< Bit resolution
+ uint8_t bSamFreqType; //!< Number of supported sampling frequencies
+ uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries)
+} app_usbd_audio_as_format_type_three_desc_t;
+
+/**
+ * @brief Audio class audio endpoint descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_EP_SUBTYPE_GENERAL
+ uint8_t bmAttributes; //!< Audio endpoint attributes
+ uint8_t bLockDelayUnits; //!< Lock delay units
+ uint8_t wLockDelay[2]; //!< Lock delay value
+} app_usbd_audio_as_endpoint_desc_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_TYPES_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c
new file mode 100644
index 0000000..3df941c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c
@@ -0,0 +1,1190 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
+
+#include "app_usbd_cdc_acm.h"
+#include <inttypes.h>
+
+/**
+ * @defgroup app_usbd_cdc_acm_internal CDC ACM internals
+ * @{
+ * @ingroup app_usbd_cdc
+ * @internal
+ */
+
+
+#define NRF_LOG_MODULE_NAME cdc_acm
+
+#if APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define APP_USBD_CDC_ACM_COMM_IFACE_IDX 0 /**< CDC ACM class comm interface index. */
+#define APP_USBD_CDC_ACM_DATA_IFACE_IDX 1 /**< CDC ACM class data interface index. */
+
+#define APP_USBD_CDC_ACM_COMM_EPIN_IDX 0 /**< CDC ACM comm class endpoint IN index. */
+#define APP_USBD_CDC_ACM_DATA_EPIN_IDX 0 /**< CDC ACM data class endpoint IN index. */
+#define APP_USBD_CDC_ACM_DATA_EPOUT_IDX 1 /**< CDC ACM data class endpoint OUT index. */
+
+/**
+ * @brief Auxiliary function to access cdc_acm class instance data.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return CDC ACM class instance.
+ */
+static inline app_usbd_cdc_acm_t const * cdc_acm_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_cdc_acm_t const *)p_inst;
+}
+
+/**
+ * @brief Auxiliary function to access cdc_acm class context data.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance data.
+ *
+ * @return CDC ACM class instance context.
+ */
+static inline app_usbd_cdc_acm_ctx_t * cdc_acm_ctx_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ ASSERT(p_cdc_acm != NULL);
+ ASSERT(p_cdc_acm->specific.p_data != NULL);
+ return &p_cdc_acm->specific.p_data->ctx;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ if (p_cdc_acm->specific.inst.user_ev_handler != NULL)
+ {
+ p_cdc_acm->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM COMM IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t comm_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_COMM_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM DATA IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t data_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM DATA OUT endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return OUT endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by CDC class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_CDC_REQ_GET_LINE_CODING:
+ {
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_cdc_acm_ctx->line_coding,
+ sizeof(app_usbd_cdc_line_coding_t));
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Class specific OUT request data callback.
+ *
+ * @param status Endpoint status.
+ * @param p_context Context of transfer (set by @ref app_usbd_core_setup_data_handler_set).
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ app_usbd_cdc_acm_t const * p_cdc_acm = p_context;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_cdc_acm_ctx->request.type)
+ {
+ case APP_USBD_CDC_REQ_SET_LINE_CODING:
+ {
+ memcpy(&p_cdc_acm_ctx->line_coding,
+ &p_cdc_acm_ctx->request.payload.line_coding,
+ sizeof(app_usbd_cdc_line_coding_t));
+
+ NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, "
+ "format: %u, parity: %u",
+ uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate),
+ p_cdc_acm_ctx->line_coding.bDataBits,
+ p_cdc_acm_ctx->line_coding.bCharFormat,
+ p_cdc_acm_ctx->line_coding.bParityType);
+ break;
+ }
+ default:
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Class specific request data stage setup.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ p_cdc_acm_ctx->request.type = p_setup_ev->setup.bmRequest;
+ p_cdc_acm_ctx->request.len = p_setup_ev->setup.wLength.w;
+
+ /*Request setup data*/
+ NRF_DRV_USBD_TRANSFER_OUT(transfer,
+ &p_cdc_acm_ctx->request.payload,
+ p_cdc_acm_ctx->request.len);
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ const app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = cdc_acm_req_out_data_cb,
+ .p_context = (void*)p_cdc_acm
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+/**
+ * @brief Reset port to default state.
+ *
+ * @param p_inst Generic class instance.
+ */
+static void cdc_acm_reset_port(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ p_cdc_acm_ctx->line_state = 0;
+
+ // Set rx transfers configuration to default state.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ p_cdc_acm_ctx->bytes_left = 0;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->last_read = 0;
+ p_cdc_acm_ctx->cur_read = 0;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_CDC_REQ_SET_LINE_CODING:
+ {
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return cdc_acm_req_out_datastage(p_inst, p_setup_ev);
+ }
+ case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE:
+ {
+ if (p_setup_ev->setup.wLength.w != 0)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x", p_setup_ev->setup.wValue.w);
+
+ bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+ p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w;
+
+ bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+
+ if (old_dtr == new_dtr)
+ {
+ return NRF_SUCCESS;
+ }
+
+ const app_usbd_cdc_acm_user_event_t ev = new_dtr ?
+ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE;
+
+ user_event_handler(p_inst, ev);
+
+ if (!new_dtr)
+ {
+ /*Abort DATA endpoints on port close */
+ nrf_drv_usbd_ep_t ep;
+ ep = data_ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_abort(ep);
+ ep = data_ep_out_addr_get(p_inst);
+ nrf_drv_usbd_ep_abort(ep);
+
+ // Set rx transfers configuration to default state.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ p_cdc_acm_ctx->bytes_left = 0;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->last_read = 0;
+ p_cdc_acm_ctx->cur_read = 0;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
+ }
+
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Control endpoint handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief CDC ACM consumer
+ *
+ * @note See @ref nrf_drv_usbd_consumer_t
+ */
+static bool cdc_acm_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
+ p_next->size = data_size;
+
+ if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
+
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += data_size;
+ p_cdc_acm_ctx->bytes_read += data_size;
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
+ data_size,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+ return (p_cdc_acm_ctx->rx_transfer[0].read_left) != 0;
+ }
+ else
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
+
+ p_cdc_acm_ctx->cur_read = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
+ return false;
+ }
+}
+
+/**
+ * @brief CDC ACM single transfer consumer
+ *
+ * This function finalizes transfer after any received block
+ *
+ * @note See @ref nrf_drv_usbd_consumer_t
+ */
+static bool cdc_acm_single_shoot_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
+ p_next->size = data_size;
+
+ if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
+
+ p_cdc_acm_ctx->bytes_read = data_size;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
+ data_size,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+ }
+ else
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
+ p_cdc_acm_ctx->cur_read = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
+ }
+
+ return false;
+}
+
+/**
+ * @brief Manage switching between user buffers and copying data from internal buffer.
+ *
+ * @param p_inst Generic USB class instance.
+ *
+ * @return Standard error code
+ */
+static ret_code_t cdc_acm_rx_block_finished(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_handler_desc_t handler_desc = {
+ .handler.consumer = cdc_acm_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ if (p_cdc_acm_ctx->rx_transfer[0].read_left == 0) // Buffer completely filled by consumer
+ {
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->bytes_left = 0;
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ return app_usbd_ep_handled_transfer(ep, &handler_desc);
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ return NRF_SUCCESS;
+ }
+ }
+
+ size_t bytes_read = p_cdc_acm_ctx->cur_read;
+ size_t bytes_to_cpy = bytes_read;
+
+ if (bytes_read > p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ bytes_to_cpy = p_cdc_acm_ctx->rx_transfer[0].read_left;
+ }
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->internal_rx_buf,
+ bytes_to_cpy);
+
+ // First buffer is full
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read + bytes_to_cpy;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->bytes_left = bytes_read - bytes_to_cpy;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf + bytes_to_cpy;
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ // If there is second transfer, copy it to first
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+
+ while (p_cdc_acm_ctx->bytes_left > 0)
+ {
+
+ if (p_cdc_acm_ctx->bytes_left >= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ // If there are enough bytes left in internal buffer to completely fill next transfer,
+ // we call user event handler to obtain next buffer and continue double buffering.
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+
+ p_cdc_acm_ctx->bytes_left -= p_cdc_acm_ctx->rx_transfer[0].read_left;
+ p_cdc_acm_ctx->p_copy_pos += p_cdc_acm_ctx->rx_transfer[0].read_left;
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->rx_transfer[0].read_left;
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ }
+ else
+ {
+ // If user does not specify a second buffer, all data transfers are done
+ // and data left in internal buffer is lost.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ break;
+ }
+ }
+ else
+ {
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->bytes_left);
+ p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
+
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
+ break;
+ }
+ }
+
+
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ }
+
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf != NULL)
+ {
+ return app_usbd_ep_handled_transfer(ep, &handler_desc);
+ }
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Class specific endpoint transfer handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ if (comm_ep_in_addr_get(p_inst) == p_event->drv_evt.data.eptransfer.ep)
+ {
+ NRF_LOG_INFO("EPIN_COMM: notify");
+ return NRF_SUCCESS;
+ }
+ ret_code_t ret;
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ switch (p_event->drv_evt.data.eptransfer.status)
+ {
+ case NRF_USBD_EP_OK:
+ NRF_LOG_INFO("EPIN_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_TX_DONE);
+ return NRF_SUCCESS;
+ case NRF_USBD_EP_ABORTED:
+ return NRF_SUCCESS;
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ switch (p_event->drv_evt.data.eptransfer.status)
+ {
+ case NRF_USBD_EP_OK:
+ ret = cdc_acm_rx_block_finished(p_inst);
+ NRF_LOG_INFO("EPOUT_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
+ return ret;
+ case NRF_USBD_EP_WAITING:
+ case NRF_USBD_EP_ABORTED:
+ return NRF_SUCCESS;
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ cdc_acm_reset_port(p_inst);
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ ret = cdc_acm_endpoint_ev(p_inst, p_event);
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ break;
+ case APP_USBD_EVT_POWER_REMOVED:
+ cdc_acm_reset_port(p_inst);
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+static bool cdc_acm_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* INTERFACE ASSOCIATION DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x08); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION); // bDescriptorType = Interface Association
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface); // bFirstInterface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02); // bInterfaceCount
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS); // bFunctionClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM); // bFunctionSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol); // bFunctionProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iFunction
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+
+ if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS); // bInterfaceClass = CDC COMM
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM); // bInterfaceSubclass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol); // bInterfaceProtocol
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_DATA_CLASS); // bInterfaceClass = CDC DATA
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterfaceSubclass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterfaceProtocol
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ /* HEADER DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_HEADER); // bDescriptorSubtype = Header Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x10); // bcdCDC LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bcdCDC MSB
+
+ /* CALL MANAGEMENT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_CALL_MGMT); // bDescriptorSubtype = Call Management Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x03); // bmCapabilities
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface); // bDataInterface
+
+ /* ABSTRACT CONTROL MANAGEMENT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x04); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_ACM); // bDescriptorSubtype = Abstract Control Management Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02); // bmCapabilities
+
+ /* UNION DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_UNION); // bDescriptorSubtype = Union Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface); // bControlInterface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface); // bSubordinateInterface
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ ;
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ /* ENDPOINT DESCRIPTORS */
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ static uint8_t j = 0;
+
+ for (j = 0; j < endpoints; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+
+ if (p_cdc_acm->specific.inst.comm_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK); // bmAttributes
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+
+ if (p_cdc_acm->specific.inst.comm_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(16); // bInterval
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterval
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ }
+
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/**
+ * @brief Public cdc_acm class interface
+ *
+ */
+const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = {
+ .event_handler = cdc_acm_event_handler,
+ .feed_descriptors = cdc_acm_feed_descriptors,
+};
+
+/** @} */
+
+ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
+ const void * p_buf,
+ size_t length)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+ if (!dtr_state)
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ nrf_drv_usbd_ep_t ep = data_ep_in_addr_get(p_inst);
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_buf, length);
+ return app_usbd_ep_transfer(ep, &transfer);
+}
+
+size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ return p_cdc_acm_ctx->last_read;
+}
+
+size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ return p_cdc_acm_ctx->bytes_left;
+}
+
+ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length)
+{
+ ASSERT(p_buf != NULL);
+ ret_code_t ret;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_ENTER();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
+ {
+ if (p_cdc_acm_ctx->bytes_left >= length)
+ {
+ memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, length);
+ p_cdc_acm_ctx->bytes_left -= length;
+ p_cdc_acm_ctx->p_copy_pos += length;
+ p_cdc_acm_ctx->last_read = length;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = length;
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
+ nrf_drv_usbd_handler_desc_t const handler_desc = {
+ .handler.consumer = cdc_acm_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ if (p_cdc_acm_ctx->bytes_left > 0)
+ {
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->bytes_left);
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->bytes_left = 0;
+
+ }
+ ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
+ if (ret == NRF_SUCCESS)
+ {
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ }
+ }
+ else if (p_cdc_acm_ctx->rx_transfer[1].p_buf == NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[1].read_left = length;
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ else
+ {
+ ret = NRF_ERROR_BUSY;
+ }
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ return ret;
+}
+
+ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length)
+{
+ ASSERT(p_buf != NULL);
+ ret_code_t ret;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_ENTER();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ if (p_cdc_acm_ctx->bytes_left > 0)
+ {
+ size_t to_copy = MIN(length, p_cdc_acm_ctx->bytes_left);
+ memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, to_copy);
+ p_cdc_acm_ctx->bytes_left -= to_copy;
+ p_cdc_acm_ctx->p_copy_pos += to_copy;
+ p_cdc_acm_ctx->last_read = to_copy;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = length;
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
+ nrf_drv_usbd_handler_desc_t const handler_desc = {
+ .handler.consumer = cdc_acm_single_shoot_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
+ if (ret == NRF_SUCCESS)
+ {
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ }
+ else
+ {
+ ret = NRF_ERROR_BUSY;
+ }
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ return ret;
+}
+
+static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ nrf_drv_usbd_ep_t ep = comm_ep_in_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_OUT(transfer,
+ &p_cdc_acm_ctx->request.payload,
+ sizeof(app_usbd_cdc_acm_notify_t));
+ return app_usbd_ep_transfer(ep, &transfer);
+}
+
+ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_serial_state_t serial_state,
+ bool value)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = NRF_SUCCESS;
+ switch (serial_state)
+ {
+ case APP_USBD_CDC_ACM_SERIAL_STATE_DCD:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_DSR:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_BREAK:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_RING:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_PARITY:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN:
+
+ if (value)
+ {
+ p_cdc_acm_ctx->serial_state |= serial_state;
+ }
+ else
+ {
+ p_cdc_acm_ctx->serial_state &= ~serial_state;
+ }
+
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_cdc_acm_notify_t * notify = &p_cdc_acm_ctx->request.payload.notify;
+ notify->cdc_notify.bmRequestType = app_usbd_setup_req_val(APP_USBD_SETUP_REQREC_INTERFACE,
+ APP_USBD_SETUP_REQTYPE_CLASS,
+ APP_USBD_SETUP_REQDIR_IN);
+ notify->cdc_notify.bmRequest = APP_USBD_CDC_NOTIF_SERIAL_STATE;
+ notify->cdc_notify.wValue = 0;
+ notify->cdc_notify.wIndex = 0;
+ notify->cdc_notify.wLength = sizeof(notify->serial_state);
+
+ notify->serial_state = p_cdc_acm_ctx->serial_state;
+
+ ret = cdc_acm_serial_state_notify(p_cdc_acm);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_line_state_t line_state,
+ uint32_t * value)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = NRF_SUCCESS;
+ switch (line_state)
+ {
+ case APP_USBD_CDC_ACM_LINE_STATE_DTR:
+ case APP_USBD_CDC_ACM_LINE_STATE_RTS:
+ *value = (p_cdc_acm_ctx->line_state & line_state) != 0;
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h
new file mode 100644
index 0000000..5af0226
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h
@@ -0,0 +1,362 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_ACM_H__
+#define APP_USBD_CDC_ACM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_cdc_desc.h"
+#include "app_usbd_cdc_types.h"
+#include "app_usbd_cdc_acm_internal.h"
+
+/**
+ * @defgroup app_usbd_cdc_acm USB CDC ACM class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions and API used by CDC ACM class.
+ *
+ * @details References:
+ * - "Universal Serial Bus Class Definitions for Communications Devices"
+ * Revision 1.2, November 3, 2010
+ * - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices"
+ * Revision 1.2, February 9, 2007
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief CDC ACM class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_cdc_acm_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_cdc_acm, \
+ APP_USBD_CDC_ACM_CONFIG(0, 0, 0, 0, 0), \
+ APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler.
+ *
+ * @note Example prototype of user event handler:
+ *
+ * @code
+ void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+ * @endcode
+ */
+typedef enum app_usbd_cdc_acm_user_event_e {
+ APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE. */
+ APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE. */
+
+ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN. */
+ APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE. */
+} app_usbd_cdc_acm_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Default CDC ACM descriptors.
+ *
+ * @param comm_interface COMM interface number.
+ * @param comm_epin COMM interface IN endpoint.
+ * @param data_interface DATA interface number.
+ * @param data_epin DATA interface IN endpoint.
+ * @param data_epout DATA interface OUT endpoint.
+ */
+#define APP_USBD_CDC_ACM_DEFAULT_DESC(comm_interface, \
+ comm_epin, \
+ data_interface, \
+ data_epin, \
+ data_epout) \
+ APP_USBD_CDC_IAD_DSC(comm_interface, \
+ APP_USBD_CDC_SUBCLASS_ACM, \
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
+ APP_USBD_CDC_COMM_INTERFACE_DSC(comm_interface, \
+ APP_USBD_CDC_SUBCLASS_ACM, \
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
+ APP_USBD_CDC_HEADER_DSC(0x0110) \
+ APP_USBD_CDC_CALL_MGMT_DSC(0x03, data_interface) \
+ APP_USBD_CDC_ACM_DSC(0x02) \
+ APP_USBD_CDC_UNION_DSC(comm_interface, data_interface) \
+ APP_USBD_CDC_COM_EP_DSC(comm_epin, NRF_DRV_USBD_EPSIZE) \
+ APP_USBD_CDC_DATA_INTERFACE_DSC(data_interface, 0, 0) \
+ APP_USBD_CDC_DATA_EP_DSC(data_epin, data_epout, NRF_DRV_USBD_EPSIZE)
+
+/**
+ * @brief Global definition of app_usbd_cdc_acm_t class instance.
+ *
+ * @param instance_name Name of global instance.
+ * @param user_ev_handler User event handler (optional).
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL.
+ *
+ */
+#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+ APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+
+/**
+ * @brief Helper function to get class instance from CDC ACM class.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_cdc_acm_class_inst_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ return &p_cdc_acm->base;
+}
+
+/**
+ * @brief Helper function to get cdc_acm specific request from cdc_acm class.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return CDC ACM class specific request.
+ */
+static inline app_usbd_cdc_acm_req_t *
+app_usbd_cdc_acm_class_request_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ return &p_cdc_acm->specific.p_data->ctx.request;
+}
+
+/**
+ * @brief Helper function to get cdc_acm from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return CDC ACM class handle.
+ */
+static inline app_usbd_cdc_acm_t const *
+app_usbd_cdc_acm_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_cdc_acm_t const *)p_inst;
+}
+
+
+/**
+ * @brief Writes data to CDC ACM serial port.
+ *
+ * This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event
+ * to be sure that all data has been sent and input buffer could be accessed again.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] p_buf Input buffer.
+ * @param[in] length Input buffer length.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
+ const void * p_buf,
+ size_t length);
+
+/**
+ * @brief Returns the amount of data that was read.
+ *
+ * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
+ * information how many bytes have been transfered into user buffer.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Amount of data transfered.
+ */
+size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm);
+
+/**
+ * @brief Returns the amount of data that was stored into internal buffer
+ *
+ * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
+ * information how many bytes are waiting in internal buffer.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Amount of data waiting.
+ */
+size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm);
+
+/**
+ * @brief Reads data from CDC ACM serial port.
+ *
+ * This function uses internal buffer and double buffering for continuous transmission.
+ *
+ * If there is enough data in internal buffer to fill user buffer, NRF_SUCCESS is
+ * returned and data is immediately available in the user buffer.
+ *
+ * If not, up to two user buffers can be scheduled, function returns NRF_ERROR_IO_PENDING
+ * when first buffer is filled and @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event is generated.
+ *
+ * @sa app_usbd_cdc_acm_read_any
+ * @sa app_usbd_cdc_acm_rx_size
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[out] p_buf Output buffer.
+ * @param[in] length Number of bytes to read.
+ *
+ * @retval NRF_SUCCESS Data is stored into user buffer.
+ * @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
+ * @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
+ * @retval NRF_ERROR_BUSY There are already 2 buffers queued for transfers.
+ * @retval other Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length);
+
+/**
+ * @brief Read any data from CDC ACM port up to given buffer size
+ *
+ * This function is very similar to the @ref app_usbd_cdc_acm_read but it returns
+ * data as quick as any data is available, even if the given buffer was not totally full.
+ *
+ * @note This function cannot use double buffering.
+ * @note To check the number of bytes really read use @ref app_usbd_cdc_acm_rx_size
+ * function.
+ *
+ * @sa app_usbd_cdc_acm_read
+ * @sa app_usbd_cdc_acm_rx_size
+ *
+ * @param p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[out] p_buf Output buffer.
+ * @param[in] length Maximum number of bytes to read.
+ *
+ * @retval NRF_SUCCESS Data is stored into user buffer.
+ * @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
+ * @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
+ * @retval NRF_ERROR_BUSY There is already buffer set for a transfer.
+ * @retval other Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length);
+
+/**
+ * @brief Serial state notifications.
+ * */
+typedef enum {
+ APP_USBD_CDC_ACM_SERIAL_STATE_DCD = (1u << 0), /**< Notification bit DCD. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_DSR = (1u << 1), /**< Notification bit DSR. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_BREAK = (1u << 2), /**< Notification bit BREAK. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_RING = (1u << 3), /**< Notification bit RING. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING = (1u << 4), /**< Notification bit FRAMING.*/
+ APP_USBD_CDC_ACM_SERIAL_STATE_PARITY = (1u << 5), /**< Notification bit PARITY. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN = (1u << 6), /**< Notification bit OVERRUN.*/
+} app_usbd_cdc_acm_serial_state_t;
+
+/**
+ * @brief Serial line state.
+ */
+typedef enum {
+ APP_USBD_CDC_ACM_LINE_STATE_DTR = (1u << 0), /**< Line state bit DTR.*/
+ APP_USBD_CDC_ACM_LINE_STATE_RTS = (1u << 1), /**< Line state bit RTS.*/
+} app_usbd_cdc_acm_line_state_t;
+
+/**
+ * @brief Serial state notification via IN interrupt endpoint.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] serial_state Serial state notification type.
+ * @param[in] value Serial state value.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_serial_state_t serial_state,
+ bool value);
+
+/**
+ * @brief Control line value get.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] line_state Line control value type.
+ * @param[out] value Line control value.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_line_state_t line_state,
+ uint32_t * value);
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_ACM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h
new file mode 100644
index 0000000..5e09249
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_ACM_INTERNAL_H__
+#define APP_USBD_CDC_ACM_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "app_util.h"
+
+/**
+ * @defgroup app_usbd_cdc_acm_internal USB CDC ACM internals
+ * @ingroup app_usbd_cdc_acm
+ * @brief @tagAPI52840 Internals of the USB ACM class implementation.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in cdc_acm class.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_cdc_acm);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_cdc_acm_user_event_e.
+ *
+ */
+enum app_usbd_cdc_acm_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event User event.
+ *
+ */
+typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_cdc_acm_user_event_e event);
+
+/**
+ * @brief CDC ACM class part of class instance data.
+ */
+typedef struct {
+ uint8_t comm_interface; //!< Interface number of cdc_acm control.
+ uint8_t comm_epin; //!< COMM subclass IN endpoint.
+ uint8_t data_interface; //!< Interface number of cdc_acm DATA.
+ uint8_t data_epout; //!< DATA subclass OUT endpoint.
+ uint8_t data_epin; //!< DATA subclass IN endpoint.
+
+ app_usbd_cdc_comm_protocol_t protocol; //!< User specified CDC protocol.
+
+ app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler.
+} app_usbd_cdc_acm_inst_t;
+
+
+/**
+ * @brief CDC ACM serial state class notify
+ */
+typedef struct {
+ app_usbd_cdc_notify_t cdc_notify; //!< CDC notify.
+ uint16_t serial_state; //!< Serial port state.
+} app_usbd_cdc_acm_notify_t;
+
+/**
+ * @brief CDC ACM class specific request handled via control endpoint.
+ */
+typedef struct {
+ uint8_t type; //!< Request type.
+ uint8_t len; //!< Request length.
+
+ union {
+ app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
+ app_usbd_cdc_acm_notify_t notify; //!< CDC ACM class notify.
+ } payload;
+} app_usbd_cdc_acm_req_t;
+
+/**
+ * @brief CDC ACM rx transfer buffer
+ */
+typedef struct {
+ uint8_t * p_buf; //!< User buffer pointer.
+ size_t read_left; //!< Bytes left to read into buffer.
+} cdc_rx_buffer_t;
+
+/**
+ * @brief CDC ACM class context
+ */
+typedef struct {
+ app_usbd_cdc_acm_req_t request; //!< CDC ACM class request.
+ app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
+
+ uint16_t line_state; //!< CDC ACM line state bitmap, DTE side.
+ uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side.
+
+ cdc_rx_buffer_t rx_transfer[2]; //!< User receive transfers.
+
+ uint8_t internal_rx_buf[NRF_DRV_USBD_EPSIZE]; //!< Internal receive buffer.
+ uint8_t * p_copy_pos; //!< Current copy position from internal buffer.
+
+ size_t bytes_left; //!< Bytes left in internal buffer to copy.
+ size_t bytes_read; //!< Bytes currently written to user buffer.
+ size_t last_read; //!< Bytes read in last transfer.
+ size_t cur_read; //!< Bytes currently read to internal buffer.
+} app_usbd_cdc_acm_ctx_t;
+
+
+/**
+ * @brief CDC ACM class configuration macro.
+ *
+ * Used by @ref APP_USBD_CDC_ACM_GLOBAL_DEF
+ *
+ * @param iface_comm Interface number of cdc_acm control.
+ * @param epin_comm COMM subclass IN endpoint.
+ * @param iface_data Interface number of cdc_acm DATA.
+ * @param epin_data DATA subclass IN endpoint.
+ * @param epout_data DATA subclass OUT endpoint.
+ *
+ */
+#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \
+ ((iface_comm, epin_comm), \
+ (iface_data, epin_data, epout_data))
+
+
+/**
+ * @brief Specific class constant data for cdc_acm class.
+ *
+ * @ref app_usbd_cdc_acm_inst_t
+ */
+#define APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC app_usbd_cdc_acm_inst_t inst;
+
+
+/**
+ * @brief Configures cdc_acm class instance.
+ *
+ * @param user_event_handler User event handler.
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol.
+ */
+#define APP_USBD_CDC_ACM_INST_CONFIG(user_event_handler, comm_ifc, comm_ein, data_ifc, data_ein, \
+ data_eout, cdc_protocol) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .comm_interface = comm_ifc, \
+ .comm_epin = comm_ifc, \
+ .data_interface = data_ifc, \
+ .data_epin = data_ein, \
+ .data_epout = data_eout, \
+ .protocol = cdc_protocol \
+ }
+
+/**
+ * @brief Specific class data for cdc_acm class.
+ *
+ * @ref app_usbd_cdc_acm_ctx_t
+ */
+#define APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC app_usbd_cdc_acm_ctx_t ctx;
+
+
+/**
+ * @brief CDC ACM class descriptors config macro.
+ *
+ * @param interface_number Interface number.
+ * @param ... Extracted endpoint list.
+ */
+#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \
+ 0, \
+ 0, \
+ APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \
+}
+
+/**
+ * @brief Public cdc_acm class interface.
+ *
+ */
+extern const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_cdc_acm_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param user_ev_handler User event handler.
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL)*/
+#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_cdc_acm, \
+ &app_usbd_cdc_acm_class_methods, \
+ APP_USBD_CDC_ACM_CONFIG(comm_ifc, comm_ein, data_ifc, data_ein, data_eout), \
+ (APP_USBD_CDC_ACM_INST_CONFIG(user_ev_handler, \
+ comm_ifc, \
+ comm_ein, \
+ data_ifc, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol)) \
+ )
+/*lint -restore*/
+
+/** @} */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_ACM_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h
new file mode 100644
index 0000000..091065d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_DESC_H__
+#define APP_USBD_CDC_DESC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "app_usbd_descriptor.h"
+#include "app_usbd_cdc_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_cdc_desc CDC class descriptors
+ * @brief @tagAPI52840 Descriptors used in the USB CDC class implementation.
+ * @ingroup app_usbd_cdc_acm
+ *
+ * A group of macros used to initialize CDC descriptors
+ * @{
+ */
+
+/**
+ * @brief Initializer of IAD descriptor for CDC class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
+ */
+#define APP_USBD_CDC_IAD_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iad_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION, \
+ /*.bFirstInterface = */ interface_number, \
+ /*.bInterfaceCount = */ 2, \
+ /*.bFunctionClass = */ APP_USBD_CDC_COMM_CLASS, \
+ /*.bFunctionSubClass = */ subclass, \
+ /*.bFunctionProtocol = */ protocol, \
+ /*.iFunction = */ 0, \
+
+/**
+ * @brief Initializer of interface descriptor for CDC COMM class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
+ */
+#define APP_USBD_CDC_COMM_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 1, \
+ /*.bInterfaceClass = */ APP_USBD_CDC_COMM_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of interface descriptor for CDC DATA class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_data_protocol_t.
+ */
+#define APP_USBD_CDC_DATA_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 2, \
+ /*.bInterfaceClass = */ APP_USBD_CDC_DATA_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+
+/**
+ * @brief Initializer of endpoint descriptor for CDC COM class.
+ *
+ * @param endpoint_in IN endpoint.
+ * @param ep_size Endpoint size.
+ */
+#define APP_USBD_CDC_COM_EP_DSC(endpoint_in, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 16, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param endpoint_in IN endpoint.
+ * @param endpoint_out OUT endpoint.
+ * @param ep_size Endpoint size.
+ */
+#define APP_USBD_CDC_DATA_EP_DSC(endpoint_in, endpoint_out, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_out, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC header descriptor.
+ *
+ * @param bcd_cdc BCD CDC version.
+ */
+#define APP_USBD_CDC_HEADER_DSC(bcd_cdc) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_header_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_HEADER, \
+ /*.bcdCDC = */ APP_USBD_U16_TO_RAW_DSC(bcd_cdc), \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC call management descriptor.
+ *
+ * @param capabilities Capabilities.
+ * @param data_interface Data interface.
+ */
+#define APP_USBD_CDC_CALL_MGMT_DSC(capabilities, data_interface) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_call_mgmt_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_CALL_MGMT, \
+ /*.bmCapabilities = */ capabilities, \
+ /*.bDataInterface = */ data_interface, \
+
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param capabilities Capabilities.
+ */
+#define APP_USBD_CDC_ACM_DSC(capabilities) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_acm_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_ACM, \
+ /*.bmCapabilities = */ capabilities, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param control_interface Control interface.
+ * @param ... Subordinate interfaces list.
+ */
+#define APP_USBD_CDC_UNION_DSC(control_interface, ...) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_union_t) + (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_UNION, \
+ /*.bControlInterface = */ control_interface, \
+ /*.bSubordinateInterface = */ __VA_ARGS__, \
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h
new file mode 100644
index 0000000..9b8a482
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h
@@ -0,0 +1,360 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_TYPES_H__
+#define APP_USBD_CDC_TYPES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_cdc_types CDC class types
+ * @ingroup app_usbd_cdc_acm
+ *
+ * @brief @tagAPI52840 Variable types used by the CDC class implementation.
+ * @{
+ */
+
+/**
+ * @brief Communications Interface Class code.
+ *
+ * Used for control interface in communication class.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ */
+#define APP_USBD_CDC_COMM_CLASS 0x02
+
+/**
+ * @brief Data Class Interface code.
+ *
+ * Used for data interface in communication class.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ */
+#define APP_USBD_CDC_DATA_CLASS 0x0A
+
+/**
+ * @brief CDC subclass possible values.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ */
+typedef enum {
+ APP_USBD_CDC_SUBCLASS_RESERVED = 0x00, /**< Reserved in documentation. */
+ APP_USBD_CDC_SUBCLASS_DLCM = 0x01, /**< Direct Line Control Model. */
+ APP_USBD_CDC_SUBCLASS_ACM = 0x02, /**< Abstract Control Model. */
+ APP_USBD_CDC_SUBCLASS_TCM = 0x03, /**< Telephone Control Model. */
+ APP_USBD_CDC_SUBCLASS_MCCM = 0x04, /**< Multi-Channel Control Model. */
+ APP_USBD_CDC_SUBCLASS_CAPI = 0x05, /**< CAPI Control Model. */
+ APP_USBD_CDC_SUBCLASS_ENCM = 0x06, /**< Ethernet Networking Control Model. */
+ APP_USBD_CDC_SUBCLASS_ATM = 0x07, /**< ATM Networking Control Model. */
+ APP_USBD_CDC_SUBCLASS_WHCM = 0x08, /**< Wireless Handset Control Model. */
+ APP_USBD_CDC_SUBCLASS_DM = 0x09, /**< Device Management. */
+ APP_USBD_CDC_SUBCLASS_MDLM = 0x0A, /**< Mobile Direct Line Model. */
+ APP_USBD_CDC_SUBCLASS_OBEX = 0x0B, /**< OBEX. */
+ APP_USBD_CDC_SUBCLASS_EEM = 0x0C, /**< Ethernet Emulation Model. */
+ APP_USBD_CDC_SUBCLASS_NCM = 0x0D /**< Network Control Model. */
+} app_usbd_cdc_subclass_t;
+
+/**
+ * @brief CDC protocol possible values.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ */
+typedef enum {
+ APP_USBD_CDC_COMM_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250 = 0x01, /**< AT Commands: V.250 etc. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101 = 0x02, /**< AT Commands defined by PCCA-101. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101_ANNEXO = 0x03, /**< AT Commands defined by PCCA-101 & Annex O. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_GSM707 = 0x04, /**< AT Commands defined by GSM 07.07. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_3GPP_27007 = 0x05, /**< AT Commands defined by 3GPP 27.007. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_CDMA = 0x06, /**< AT Commands defined by TIA for CDMA. */
+ APP_USBD_CDC_COMM_PROTOCOL_EEM = 0x07, /**< Ethernet Emulation Model. */
+ APP_USBD_CDC_COMM_PROTOCOL_EXTERNAL = 0xFE, /**< External Protocol: Commands defined by Command Set Functional Descriptor. */
+ APP_USBD_CDC_COMM_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
+} app_usbd_cdc_comm_protocol_t;
+
+/**
+ * @brief CDC data interface protocols possible values.
+ */
+typedef enum {
+ APP_USBD_CDC_DATA_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
+ APP_USBD_CDC_DATA_PROTOCOL_NTB = 0x01, /**< Network Transfer Block. */
+ APP_USBD_CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, /**< Physical interface protocol for ISDN BRI. */
+ APP_USBD_CDC_DATA_PROTOCOL_HDLC = 0x31, /**< HDLC. */
+ APP_USBD_CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, /**< Transparent. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921M = 0x50, /**< Management protocol for Q.921 data link protocol. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921 = 0x51, /**< Data link protocol for Q.921. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921TM = 0x52, /**< TEI-multiplexor for Q.921 data link protocol. */
+ APP_USBD_CDC_DATA_PROTOCOL_V42BIS = 0x90, /**< Data compression procedures. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q931 = 0x91, /**< Euro-ISDN protocol control. */
+ APP_USBD_CDC_DATA_PROTOCOL_V120 = 0x92, /**< V.24 rate adaptation to ISDN. */
+ APP_USBD_CDC_DATA_PROTOCOL_CAPI20 = 0x93, /**< CAPI Commands. */
+ APP_USBD_CDC_DATA_PROTOCOL_HOST = 0xFD, /**< Host based driver.
+ * @note This protocol code should only be used in messages
+ * between host and device to identify the host driver portion
+ * of a protocol stack.
+ */
+ APP_USBD_CDC_DATA_PROTOCOL_EXTERNAL = 0xFE, /**< The protocol(s) are described using a Protocol Unit Functional
+ * Descriptors on Communications Class Interface.
+ */
+ APP_USBD_CDC_DATA_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
+} app_usbd_cdc_data_protocol_t;
+
+/**
+ * @brief CDC Functional Descriptor types.
+ */
+typedef enum {
+ APP_USBD_CDC_CS_INTERFACE = 0x24, /**< Class specific interface descriptor type.*/
+ APP_USBD_CDC_CS_ENDPOINT = 0x25 /**< Class specific endpoint descriptor type.*/
+} app_usbd_cdc_func_type_t;
+
+/**
+ * @brief CDC Functional Descriptor subtypes
+ */
+typedef enum {
+ APP_USBD_CDC_SCS_HEADER = 0x00, /**< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. */
+ APP_USBD_CDC_SCS_CALL_MGMT = 0x01, /**< Call Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_ACM = 0x02, /**< Abstract Control Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_DLM = 0x03, /**< Direct Line Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_R = 0x04, /**< Telephone Ringer Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_CAP = 0x05, /**< Telephone Call and Line State Reporting Capabilities Functional Descriptor. */
+ APP_USBD_CDC_SCS_UNION = 0x06, /**< Union Functional Descriptor. */
+ APP_USBD_CDC_SCS_COUNTRY_SEL = 0x07, /**< Country Selection Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_OM = 0x08, /**< Telephone Operational Modes Functional Descriptor. */
+ APP_USBD_CDC_SCS_USB_TERM = 0x09, /**< USB Terminal Functional Descriptor. */
+ APP_USBD_CDC_SCS_NCT = 0x0A, /**< Network Channel Terminal Descriptor. */
+ APP_USBD_CDC_SCS_PU = 0x0B, /**< Protocol Unit Functional Descriptor. */
+ APP_USBD_CDC_SCS_EU = 0x0C, /**< Extension Unit Functional Descriptor. */
+ APP_USBD_CDC_SCS_MCM = 0x0D, /**< Multi-Channel Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_CAPI = 0x0E, /**< CAPI Control Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_ETH = 0x0F, /**< Ethernet Networking Functional Descriptor. */
+ APP_USBD_CDC_SCS_ATM = 0x10, /**< ATM Networking Functional Descriptor. */
+ APP_USBD_CDC_SCS_WHCM = 0x11, /**< Wireless Handset Control Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_MDLM = 0x12, /**< Mobile Direct Line Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_MDLM_DET = 0x13, /**< MDLM Detail Functional Descriptor. */
+ APP_USBD_CDC_SCS_DMM = 0x14, /**< Device Management Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_OBEX = 0x15, /**< OBEX Functional Descriptor. */
+ APP_USBD_CDC_SCS_CS = 0x16, /**< Command Set Functional Descriptor. */
+ APP_USBD_CDC_SCS_CS_DET = 0x17, /**< Command Set Detail Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_CM = 0x18, /**< Telephone Control Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_OBEX_SI = 0x19, /**< OBEX Service Identifier Functional Descriptor. */
+ APP_USBD_CDC_SCS_NCM = 0x1A /**< NCM Functional Descriptor. */
+} app_usbd_cdc_func_subtype_t;
+
+/* Make all descriptors packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Header Functional Descriptor
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this descriptor in bytes.
+ uint8_t bDescriptorType; //!< @ref APP_USBD_CDC_CS_INTERFACE descriptor type.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_HEADER.
+ uint8_t bcdCDC[2]; //!< USB Class Definitions for Communications Devices Specification release number in binary-coded decimal.
+} app_usbd_cdc_desc_header_t;
+
+/**
+ * @brief Call management capabilities.
+ *
+ * @ref app_usbd_cdc_desc_call_mgmt_t::bmCapabilities bit
+ * */
+typedef enum {
+ APP_USBD_CDC_CALL_MGMT_SUPPORTED = (1 << 0), /**< Call management capability bit 0.*/
+ APP_USBD_CDC_CALL_MGMT_OVER_DCI = (1 << 1), /**< Call management capability bit 1.*/
+} app_subd_cdc_call_mgmt_cap_t;
+
+/**
+ * @brief CDC Call Management Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_CALL_MGMT.
+ uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_call_mgmt_cap_t.
+ uint8_t bDataInterface; //!< Data interface number.
+} app_usbd_cdc_desc_call_mgmt_t;
+
+/**
+ * @brief ACM capabilities.
+ *
+ * @ref app_usbd_cdc_desc_acm_t::bmCapabilities bit
+ * */
+typedef enum {
+ APP_USBD_CDC_ACM_FEATURE_REQUESTS = (1 << 0), /**< ACM capability bit FEATURE_REQUESTS. */
+ APP_USBD_CDC_ACM_LINE_REQUESTS = (1 << 1), /**< ACM capability bit LINE_REQUESTS. */
+ APP_USBD_CDC_ACM_SENDBREAK_REQUESTS = (1 << 2), /**< ACM capability bit SENDBREAK_REQUESTS.*/
+ APP_USBD_CDC_ACM_NOTIFY_REQUESTS = (1 << 3), /**< ACM capability bit NOTIFY_REQUESTS. */
+} app_subd_cdc_acm_cap_t;
+
+/**
+ * @brief CDC ACM Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_ACM.
+ uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_acm_cap_t.
+} app_usbd_cdc_desc_acm_t;
+
+/**
+ * @brief Union Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_UNION.
+ uint8_t bControlInterface; //!< The interface number of the Communications or Data Class interface, designated as the controlling interface for the union.
+ uint8_t bSubordinateInterface[]; //!< Interface number of subordinate interfaces in the union. Number of interfaced depends on descriptor size.
+} app_usbd_cdc_desc_union_t;
+
+/**
+ * @brief Country Selection Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_COUNTRY_SEL.
+ uint8_t iCountryCodeRelDate; //!< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
+} app_usbd_cdc_desc_country_sel_t;
+
+/**
+ * @brief CDC Requests
+ *
+ */
+typedef enum {
+ /* CDC General */
+ APP_USBD_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00, /**< This request is used to issue a command in the format of the supported control protocol of the Communications Class interface. */
+ APP_USBD_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01, /**< This request is used to request a response in the format of the supported control protocol of the Communications Class interface. */
+ /* CDC PSTN */
+ APP_USBD_CDC_REQ_SET_COMM_FEATURE = 0x02, /**< This request controls the settings for a particular communications feature of a particular target. */
+ APP_USBD_CDC_REQ_GET_COMM_FEATURE = 0x03, /**< This request returns the current settings for the communications feature as selected. */
+ APP_USBD_CDC_REQ_CLEAR_COMM_FEATURE = 0x04, /**< This request controls the settings for a particular communications feature of a particular target, setting the selected feature to its default state. */
+ APP_USBD_CDC_REQ_SET_AUX_LINE_STATE = 0x10, /**< This request is used to connect or disconnect a secondary jack to POTS circuit or CODEC, depending on hook state. */
+ APP_USBD_CDC_REQ_SET_HOOK_STATE = 0x11, /**< This request is used to set the necessary PSTN line relay code for on-hook, off-hook, and caller ID states. */
+ APP_USBD_CDC_REQ_PULSE_SETUP = 0x12, /**< This request is used to prepare for a pulse-dialing cycle. */
+ APP_USBD_CDC_REQ_SEND_PULSE = 0x13, /**< This request is used to generate a specified number of make/break pulse cycles. */
+ APP_USBD_CDC_REQ_SET_PULSE_TIME = 0x14, /**< This request sets the timing of the make and break periods for pulse dialing. */
+ APP_USBD_CDC_REQ_RING_AUX_JACK = 0x15, /**< This request is used to generate a ring signal on a secondary phone jack. */
+ APP_USBD_CDC_REQ_SET_LINE_CODING = 0x20, /**< This request allows the host to specify typical asynchronous line-character formatting properties. */
+ APP_USBD_CDC_REQ_GET_LINE_CODING = 0x21, /**< This request allows the host to find out the currently configured line coding. */
+ APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, /**< This request generates RS-232/V.24 style control signals. */
+ APP_USBD_CDC_REQ_SEND_BREAK = 0x23, /**< This request sends special carrier modulation that generates an RS-232 style break. */
+ APP_USBD_CDC_REQ_SET_RINGER_PARMS = 0x30, /**< This request configures the ringer for the communications device. */
+ APP_USBD_CDC_REQ_GET_RINGER_PARMS = 0x31, /**< This request returns the ringer capabilities of the device and the current status of the device’s ringer. */
+ APP_USBD_CDC_REQ_SET_OPERATION_PARMS = 0x32, /**< Sets the operational mode for the device, between a simple mode, standalone mode and a host centric mode. */
+ APP_USBD_CDC_REQ_GET_OPERATION_PARMS = 0x33, /**< This request gets the current operational mode for the device. */
+ APP_USBD_CDC_REQ_SET_LINE_PARMS = 0x34, /**< This request is used to change the state of the line, corresponding to the interface or master interface of a union to which the command was sent. */
+ APP_USBD_CDC_REQ_GET_LINE_PARMS = 0x35, /**< This request is used to report the state of the line that corresponds to the interface or master interface of a union to which the command was sent. */
+ APP_USBD_CDC_REQ_DIAL_DIGITS = 0x36, /**< This request dials the DTMF digits over the specified line. */
+} app_usbd_cdc_req_id_t;
+
+/**
+ * @brief CDC Notifications.
+ */
+typedef enum {
+ /* CDC General */
+ APP_USBD_CDC_NOTIF_NETWORK_CONNECTION = 0x00, /**< This notification allows the device to notify the host about network connection status. */
+ APP_USBD_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, /**< This notification allows the device to notify the host that a response is available.
+ * This response can be retrieved with a subsequent GetEncapsulatedResponse request.
+ _ */
+ APP_USBD_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, /**< This notification allows the device to inform the host-networking driver
+ * that a change in either the up-link or the down-link bit rate of the connection has occurred.
+ */
+ /* CDC PSTN */
+ APP_USBD_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, /**< (DLM) This notification indicates the loop has changed on the auxiliary phone interface of the USB device. */
+ APP_USBD_CDC_NOTIF_RING_DETECT = 0x09, /**< (DLM) This notification indicates ring voltage on the POTS line interface of the USB device. */
+ APP_USBD_CDC_NOTIF_SERIAL_STATE = 0x20, /**< (ACM) This notification sends asynchronous notification of UART status. */
+ APP_USBD_CDC_NOTIF_CALL_STATE_CHANGE = 0x28, /**< (TCM) This notification identifies that a change has occurred to the state of a call on the line corresponding to the interface or union for the line. */
+ APP_USBD_CDC_NOTIF_LINE_STATE_CHANGE = 0x29 /**< (TCM) This notification identifies that a change has occurred to the state of the line corresponding to the interface or master interface of a union sending the notification message. */
+} app_usbd_cdc_notify_id_t;
+
+/**
+ * @brief Notification sent via CDC COMM endpoint.
+ * */
+typedef struct {
+ uint8_t bmRequestType; //!< Request type.
+ uint8_t bmRequest; //!< Request ID @ref app_usbd_cdc_req_id_t.
+ uint16_t wValue; //!< Value field.
+ uint16_t wIndex; //!< Index field.
+ uint16_t wLength; //!< Length of payload following.
+} app_usbd_cdc_notify_t;
+
+/**
+ * @brief CDC line coding structure.
+ */
+typedef struct {
+ uint8_t dwDTERate[4]; //!< Line baudrate.
+ uint8_t bCharFormat; //!< Character format @ref app_usbd_cdc_line_stopbit_t.
+ uint8_t bParityType; //!< Parity bits @ref app_usbd_cdc_line_parity_t.
+ uint8_t bDataBits; //!< Number of data bits.
+} app_usbd_cdc_line_coding_t;
+
+/**
+ * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bCharFormat.
+ */
+typedef enum {
+ APP_USBD_CDC_LINE_STOPBIT_1 = 0, /**< 1 stop bit. */
+ APP_USBD_CDC_LINE_STOPBIT_1_5 = 1, /**< 1.5 stop bits. */
+ APP_USBD_CDC_LINE_STOPBIT_2 = 2, /**< 2 stop bits. */
+} app_usbd_cdc_line_stopbit_t;
+
+/**
+ * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bParityType.
+ */
+typedef enum {
+ APP_USBD_CDC_LINE_PARITY_NONE = 0, /**< No parity. */
+ APP_USBD_CDC_LINE_PARITY_ODD = 1, /**< Odd parity. */
+ APP_USBD_CDC_LINE_PARITY_EVEN = 2, /**< Even parity. */
+ APP_USBD_CDC_LINE_PARITY_MARK = 3, /**< Parity forced to 0 (space).*/
+ APP_USBD_CDC_LINE_PARITY_SPACE = 4, /**< Parity forced to 1 (mark). */
+} app_usbd_cdc_line_parity_t;
+
+
+#pragma pack(pop)
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c
new file mode 100644
index 0000000..51d8721
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_DUMMY)
+
+#include <string.h>
+#include <ctype.h>
+#include "app_usbd.h"
+#include "app_usbd_dummy.h"
+#include "app_usbd_string_desc.h"
+#include "nrf_gpio.h"
+
+/**
+ * @defgroup app_usbd_dummy_internal USBD Dummy internals
+ * @{
+ * @ingroup app_usbd_dummy
+ * @internal
+ */
+
+#define NRF_LOG_MODULE_NAME usbd_dummy
+
+#if APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_DUMMY_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_DUMMY_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_DUMMY_CONFIG_DEBUG_COLOR
+#else //APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/** @brief @ref app_usbd_class_methods_t::event_handler */
+static ret_code_t dummy_class_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/** @brief @ref app_usbd_class_methods_t::feed_descriptors */
+static bool dummy_class_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static app_usbd_class_iface_conf_t const * p_cur_iface = 0;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size)
+
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_descriptor_iface_t)); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_CLASS); // bInterfaceClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_SUBCLASS); // bInterfaceSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_PROTOCOL); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+const app_usbd_class_methods_t app_usbd_dummy_class_methods = {
+ .event_handler = dummy_class_event_handler,
+ .feed_descriptors = dummy_class_feed_descriptors,
+};
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_DUMMY)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h
new file mode 100644
index 0000000..61fa819
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_DUMMY_H__
+#define APP_USBD_DUMMY_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "nrf_block_dev.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_dummy_types.h"
+#include "app_usbd_dummy_internal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_dummy USB Dummy class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions,
+ * and API used by the USB Dummy class.
+ *
+ * @note Class is used as a filler to provide correct alignement of interfaces.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Dummy class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_dummy_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_NO_EP_TYPEDEF(app_usbd_dummy, \
+ APP_USBD_DUMMY_CONFIG(0), \
+ APP_USBD_DUMMY_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_DUMMY_DATA_SPECIFIC_DEC \
+);
+#endif
+
+/*lint -restore*/
+
+/**
+ * @brief Global definition of app_usbd_dummy_t class
+ *
+ * @param instance_name Name of global instance
+ * @param interface_number Unique interface number
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_DUMMY_GLOBAL_DEF_INTERNAL
+ *
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_DUMMY_GLOBAL_DEF)*/
+#define APP_USBD_DUMMY_GLOBAL_DEF(instance_name, interface_number) \
+ APP_USBD_DUMMY_GLOBAL_DEF_INTERNAL(instance_name, interface_number)
+/*lint -restore*/
+
+/**
+ * @@brief Helper function to get class instance from dummy
+ *
+ * @param[in] p_dummy Dummy instance
+ * (declared by @ref APP_USBD_DUMMY_GLOBAL_DEF)
+ *
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_dummy_class_inst_get(app_usbd_dummy_t const * p_dummy)
+{
+ return &p_dummy->base;
+}
+
+/**
+ * @brief Helper function to get dummy from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ *
+ * @return Dummy class handle
+ */
+static inline app_usbd_dummy_t const *
+app_usbd_dummy_class_get( app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_dummy_t const *)p_inst;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_DUMMY_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h
new file mode 100644
index 0000000..5b48ae7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_DUMMY_INTERNAL_H__
+#define APP_USBD_DUMMY_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_dummy_internals USB Dummy internals
+ * @ingroup app_usbd_dummy
+ *
+ * @brief @tagAPI52840 Internals of the USB Dummy class.
+ * @{
+ */
+
+/** @brief Forward declaration of Dummy Class type */
+APP_USBD_CLASS_FORWARD(app_usbd_dummy);
+
+/** @brief Dummy part of class instance data */
+typedef struct {
+ uint8_t none;
+} app_usbd_dummy_inst_t;
+
+/** @brief Dummy context */
+typedef struct {
+ uint8_t none;
+} app_usbd_dummy_ctx_t;
+
+
+/**
+ * @brief Dummy configuration macro
+ *
+ * Used by @ref APP_USBD_DUMMY_GLOBAL_DEF
+ *
+ * @param iface Interface number
+ * */
+#define APP_USBD_DUMMY_CONFIG(iface) (iface)
+
+
+/**
+ * @brief Specific class constant data for Dummy
+ *
+ * @ref app_usbd_dummy_inst_t
+ */
+#define APP_USBD_DUMMY_INSTANCE_SPECIFIC_DEC app_usbd_dummy_inst_t inst;
+
+/**
+ * @brief Specific class data for Dummy
+ *
+ * @ref app_usbd_dummy_ctx_t
+ * */
+#define APP_USBD_DUMMY_DATA_SPECIFIC_DEC app_usbd_dummy_ctx_t ctx;
+
+
+/** @brief Public Dummy class interface */
+extern const app_usbd_class_methods_t app_usbd_dummy_class_methods;
+
+/** @brief Global definition of Dummy instance */
+#define APP_USBD_DUMMY_GLOBAL_DEF_INTERNAL(instance_name, interface_number) \
+ APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_dummy, \
+ &app_usbd_dummy_class_methods, \
+ APP_USBD_DUMMY_CONFIG((interface_number)), \
+ () \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_DUMMY_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h
new file mode 100644
index 0000000..1a624a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_DUMMY_TYPES_H__
+#define APP_USBD_DUMMY_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_dummy_types USB Dummy types
+ * @ingroup app_usbd_dummy
+ *
+ * @brief @tagAPI52840 Types used in the USB Dummy class.
+ * @{
+ */
+
+/** @brief Dummy class definition in interface descriptor
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_DUMMY_CLASS 0xFF
+
+/** @brief Dummy subclass value */
+#define APP_USBD_DUMMY_SUBCLASS 0x00
+
+/** @brief Dummy protocol value */
+#define APP_USBD_DUMMY_PROTOCOL 0x00
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_DUMMY_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c
new file mode 100644
index 0000000..d8ff316
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c
@@ -0,0 +1,508 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID)
+
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_hid.h"
+
+/**
+ * @ingroup app_usbd_hid_internals USBD HID internals
+ * @{
+ * @ingroup app_usbd_hid
+ * @internal
+ */
+
+/**
+ * @brief Test whether SOF HID transfer is required.
+ *
+ * This function handles idle period IN transfer.
+ *
+ * @param[in,out] p_hid_ctx Internal HID context.
+ * @param framecnt SOF event frame counter.
+ *
+ * @retval true Idle transfer is required.
+ * @retval false Idle transfer is not required.
+ */
+static bool hid_sof_required(app_usbd_hid_ctx_t * p_hid_ctx, uint16_t framecnt)
+{
+ if (p_hid_ctx->idle_rate == 0)
+ {
+ /* Infinite idle rate */
+ return false;
+ }
+
+ /*Idle rate has 4ms units. Every SOF event is generated with 1ms period.*/
+ uint16_t rate_ms = p_hid_ctx->idle_rate * 4;
+ if ((framecnt % rate_ms) != 0)
+ {
+ /* Idle transfer not required yet*/
+ return false;
+ }
+
+ if (p_hid_ctx->access_lock)
+ {
+ /* Access to internal data locked. Buffer is BUSY.
+ * Don't send anything. Clear transfer flag. Next transfer will be triggered
+ * from API context.*/
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ return false;
+ }
+
+ if (app_usbd_hid_trans_required(p_hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_user_event_t event)
+{
+ if (p_hinst->user_event_handler != NULL)
+ {
+ p_hinst->user_event_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by HID class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+
+ /* HID specific descriptors*/
+
+ app_usbd_class_descriptor_ctx_t desiz;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&desiz);
+ uint32_t report_size = 0;
+
+ while(p_hinst->p_hid_methods->feed_subclass_descriptor(&desiz,
+ p_inst,
+ NULL,
+ sizeof(uint8_t),
+ p_setup_ev->setup.wValue.lb)
+ )
+ {
+ report_size++;
+ }
+
+ ASSERT(report_size <= max_size);
+
+ UNUSED_RETURN_VALUE(
+ p_hinst->p_hid_methods->feed_subclass_descriptor(&desiz,
+ p_inst,
+ p_trans_buff,
+ report_size,
+ p_setup_ev->setup.wValue.lb));
+
+ return app_usbd_core_setup_rsp(
+ &p_setup_ev->setup,
+ p_trans_buff,
+ report_size);
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /*Only Set Descriptor standard OUT request is supported by HID class. However, it is optional
+ * and useless in HID cases.*/
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_HID_REQ_GET_REPORT:
+ {
+ if ((p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_INPUT) ||
+ (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_OUTPUT))
+ {
+ return p_hinst->p_hid_methods->on_get_report(p_inst, p_setup_ev);
+ }
+ else
+ {
+ break;
+ }
+ }
+ case APP_USBD_HID_REQ_GET_IDLE:
+ {
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_hid_ctx->idle_rate,
+ sizeof(p_hid_ctx->idle_rate));
+ }
+ case APP_USBD_HID_REQ_GET_PROTOCOL:
+ {
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_hid_ctx->boot_active,
+ sizeof(p_hid_ctx->boot_active));
+ }
+ default:
+ break;
+
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_HID_REQ_SET_REPORT:
+ if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_OUTPUT)
+ {
+ break;
+ }
+
+ if (p_hinst->p_hid_methods->on_get_report == NULL)
+ {
+ break;
+ }
+
+ return p_hinst->p_hid_methods->on_set_report(p_inst, p_setup_ev);
+ case APP_USBD_HID_REQ_SET_IDLE:
+ p_hid_ctx->idle_rate = p_setup_ev->setup.wValue.hb;
+ return NRF_SUCCESS;
+ case APP_USBD_HID_REQ_SET_PROTOCOL:
+ p_hid_ctx->boot_active = p_setup_ev->setup.wValue.w;
+ {
+ app_usbd_hid_user_event_t ev = (p_hid_ctx->boot_active == 0) ?
+ APP_USBD_HID_USER_EVT_SET_BOOT_PROTO :
+ APP_USBD_HID_USER_EVT_SET_REPORT_PROTO;
+
+ user_event_handler(p_inst, p_hinst, ev);
+ }
+ return NRF_SUCCESS;
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP event handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_hinst != NULL);
+ ASSERT(p_hid_ctx != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Endpoint IN event handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event)
+{
+
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK)
+ {
+ /* Notify user about last successful transfer. */
+ user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_IN_REPORT_DONE);
+ }
+
+ if (app_usbd_hid_access_lock_test(p_hid_ctx))
+ {
+ /* Access to internal data locked. Buffer is BUSY.
+ * Don't send anything. Clear transfer flag. Next transfer will be triggered
+ * from main loop context.*/
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ return NRF_SUCCESS;
+ }
+
+ return p_hinst->p_hid_methods->ep_transfer_in(p_inst);
+}
+
+/**
+ * @brief Endpoint OUT event handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event)
+{
+ if (p_hinst->p_hid_methods->ep_transfer_out == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK)
+ {
+ /* Notify user about last successful transfer. */
+ user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_OUT_REPORT_READY);
+ }
+
+ return p_hinst->p_hid_methods->ep_transfer_out(p_inst);
+}
+
+/** @} */
+
+
+ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ if (!hid_sof_required(p_hid_ctx, p_event->drv_evt.data.sof.framecnt))
+ {
+ break;
+ }
+ ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst);
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, p_hinst, p_hid_ctx, &p_event->setup_evt);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ ret = endpoint_in_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+ }
+ else
+ {
+ ret = endpoint_out_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+ }
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED);
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED);
+
+ /* Always try to trigger transfer on resume event*/
+ ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst);
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ /*SOF register: GetIdle/SetIdle support*/
+ ret = app_usbd_class_sof_register(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ ret = app_usbd_class_rwu_register(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED);
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ /*SOF unregister: GetIdle/SetIdle support*/
+ ret = app_usbd_class_sof_unregister(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ ret = app_usbd_class_rwu_unregister(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED);
+ break;
+ case APP_USBD_EVT_STARTED:
+ app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED);
+ break;
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED);
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst)
+{
+ ASSERT(p_hinst);
+ return p_hinst->p_rep_buffer_in;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h
new file mode 100644
index 0000000..c4638ab
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h
@@ -0,0 +1,515 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_H__
+#define APP_USBD_HID_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "sdk_common.h"
+#include "nrf_atomic.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_hid USB HID class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with generic HID event data processing.
+ * @{
+ */
+
+#define APP_USBD_HID_IFACE_IDX 0 /**< @brief HID instance interface index. */
+#define APP_USBD_HID_EPIN_IDX 0 /**< @brief HID instance endpoint IN index. */
+#define APP_USBD_HID_EPOUT_IDX 1 /**< @brief HID instance endpoint OUT index.*/
+
+/**
+ * @brief HID context state flags.
+ *
+ * Bit numbers in @ref app_usbd_hid_ctx_t::state_flags.
+ */
+typedef enum {
+ APP_USBD_HID_STATE_FLAG_APPENDED = 0, /**< State flag APPENDED. */
+ APP_USBD_HID_STATE_FLAG_STARTED = 1, /**< State flag STARTED. */
+ APP_USBD_HID_STATE_FLAG_SUSPENDED = 2, /**< State flag SUSPENDED. */
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS = 3, /**< State flag TRANS_IN_PROGRESS. */
+} app_usbd_hid_state_flag_t;
+
+/**
+ * @brief Events passed to user event handler.
+ *
+ * @note Example prototype of user event handler:
+ @code
+ void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_mouse_user_event_t event);
+ @endcode
+ */
+typedef enum {
+ APP_USBD_HID_USER_EVT_SET_BOOT_PROTO, /**< Event SET_BOOT_PROTOCOL. */
+ APP_USBD_HID_USER_EVT_SET_REPORT_PROTO, /**< Event SET_REPORT_PROTOCOL.*/
+ APP_USBD_HID_USER_EVT_OUT_REPORT_READY, /**< Event OUT_REPORT_READY. */
+ APP_USBD_HID_USER_EVT_IN_REPORT_DONE, /**< Event IN_REPORT_DONE. */
+} app_usbd_hid_user_event_t;
+
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event User event.
+ */
+typedef void (*app_usbd_hid_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_user_event_t event);
+
+/**@brief HID unified interface*/
+typedef struct {
+
+ /**
+ * @brief Function called on HID specific, GetReport request.
+ *
+ * This function should trigger data write to control pipe.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*on_get_report)(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev);
+
+ /**
+ * @brief Function called on HID specific, SetReport request.
+ *
+ * This function should trigger data read from control pipe. This function is not required and
+ * NULL could be pinned to this handler when output report is not defined in report descriptor.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*on_set_report)(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev);
+
+ /**
+ * @brief Function called on IN endpoint transfer.
+ *
+ * This function should trigger next endpoint IN transfer if required.
+ *
+ * @param[in] p_inst Class instance.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*ep_transfer_in)(app_usbd_class_inst_t const * p_inst);
+
+ /**
+ * @brief Function called on OUT endpoint transfer.
+ *
+ * This function should should read data from OUT endpoint. This function is not required and
+ * NULL could be pinned to this handler when class doesn't have OUT endpoint.
+ *
+ * @param[in] p_inst Class instance.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*ep_transfer_out)(app_usbd_class_inst_t const * p_inst);
+
+ /**
+ * @brief Instance feed subclass descriptor
+ *
+ * Feeds whole descriptor of the instance
+ * @param[in] p_ctx Class descriptor context
+ * @param[in,out] p_inst Instance of the class
+ * @param[out] buff Buffer for subclass descriptor
+ * @param[in] max_size Requested size of the subclass descriptor
+ * @param[in] index Index of the subclass descriptor
+ *
+ * @return True if not finished feeding the descriptor, false if done
+ */
+ bool (*feed_subclass_descriptor)(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * buff,
+ size_t max_size,
+ uint8_t index);
+} app_usbd_hid_methods_t;
+
+/**
+ * @brief HID report buffers.
+ */
+typedef struct {
+ uint8_t * p_buff;
+ size_t size;
+} app_usbd_hid_report_buffer_t;
+
+
+
+/**@brief Define OUT report buffer structure @ref app_usbd_hid_report_buffer_t.
+ *
+ * @param name Instance name.
+ * @param rep_size Output report size.
+ */
+#define APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(name, rep_size) \
+ static uint8_t CONCAT_2(name, _buf)[(rep_size)]; \
+ const app_usbd_hid_report_buffer_t name = { \
+ .p_buff = CONCAT_2(name, _buf), \
+ .size = sizeof(CONCAT_2(name, _buf)), \
+ }
+
+/**
+ * @brief HID subclass descriptor.
+ */
+
+typedef struct {
+ size_t size;
+ app_usbd_descriptor_t type;
+ uint8_t const * const p_data;
+} app_usbd_hid_subclass_desc_t;
+
+/**
+ * @brief Initializer of HID report descriptor
+ *
+ * @param name Report descriptor name
+ * @param ... Report descriptor data
+ */
+
+#define APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ __VA_ARGS__ \
+ ; \
+ static const app_usbd_hid_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_DESCRIPTOR_REPORT, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of HID physical descriptor
+ *
+ * @param name Physical descriptor name
+ * @param ... Physical descriptor data
+ */
+
+#define APP_USBD_HID_GENERIC_SUBCLASS_PHYSICAL_DESC(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ __VA_ARGS__ \
+ ; \
+ static const app_usbd_hid_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_DESCRIPTOR_PHYSICAL, \
+ CONCAT_2(name,_data) \
+ }
+
+
+/**
+ * @brief USB HID instance.
+ */
+typedef struct {
+ app_usbd_hid_subclass_desc_t const ** const p_subclass_desc; //!< HID subclass descriptors array.
+ size_t subclass_desc_count; //!< HID subclass descriptors count.
+
+ app_usbd_hid_subclass_t subclass_boot; //!< Boot device (see HID definition)
+ app_usbd_hid_protocol_t protocol; //!< HID protocol (see HID definition)
+
+ app_usbd_hid_report_buffer_t * p_rep_buffer_in; //!< Report buffer IN.
+ app_usbd_hid_report_buffer_t const * p_rep_buffer_out; //!< Report buffer OUT (only one instance).
+ app_usbd_hid_methods_t const * p_hid_methods; //!< Hid interface methods.
+ app_usbd_hid_user_ev_handler_t user_event_handler; //!< User event handler.
+} app_usbd_hid_inst_t;
+
+
+/**
+ * @brief USB HID instance initializer @ref app_usbd_hid_inst_t.
+ *
+ * @param subclass_dsc HID subclass descriptors.
+ * @param sub_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ * @param protocl HID protocol. (@ref app_usbd_hid_protocol_t)
+ * @param report_buff_in Input report buffer list.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler @ref app_usbd_hid_user_ev_handler_t.
+ @param hid_methods @ref app_usbd_hid_methods_t.
+ * */
+
+#define APP_USBD_HID_INST_CONFIG(subclass_dsc, \
+ sub_boot, \
+ protocl, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ hid_methods) \
+ { \
+ .p_subclass_desc = subclass_dsc, \
+ .subclass_desc_count = ARRAY_SIZE(subclass_dsc), \
+ .p_rep_buffer_in = report_buff_in, \
+ .p_rep_buffer_out = report_buff_out, \
+ .user_event_handler = user_ev_handler, \
+ .p_hid_methods = hid_methods, \
+ .subclass_boot = sub_boot, \
+ .protocol = protocl \
+ }
+
+/**
+ * @brief HID internal context.
+ * */
+typedef struct {
+ nrf_atomic_u32_t state_flags; //!< HID state flags @ref app_usbd_hid_state_flag_t.
+ nrf_atomic_flag_t access_lock; //!< Lock flag to internal data.
+ uint8_t idle_rate; //!< HID idle rate (4ms units).
+ uint8_t boot_active; //!< HID using boot protocol.
+} app_usbd_hid_ctx_t;
+
+
+/**
+ * @brief Locks internal hid context.
+ *
+ * Simple semaphore functionality to prevent concurrent access from application and
+ * interrupt to internal mouse data.
+ *
+ * @param[in] p_hid_ctx Internal hid context
+ */
+static inline void app_usbd_hid_access_lock(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_set(&p_hid_ctx->access_lock));
+ __DSB();
+}
+
+
+/**
+ * @brief Unlocks internal hid context.
+ *
+ * Simple semaphore functionality to prevent concurrent access from application and
+ * interrupt to internal mouse data.
+ *
+ * @param[in] p_hid_ctx Internal hid context.
+ */
+static inline void app_usbd_hid_access_unlock(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_hid_ctx->access_lock));
+ __DSB();
+}
+
+/**
+ * @brief Tests whether internal lock is acquired.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ *
+ * @retval true Locked.
+ * @retval false Unlocked.
+ */
+static inline bool app_usbd_hid_access_lock_test(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ return p_hid_ctx->access_lock != 0;
+}
+
+/**
+ * @brief Set one of the HID internal state flags.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ * @param[in] flag Flag to set.
+ */
+static inline void app_usbd_hid_state_flag_set(app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_hid_state_flag_t flag)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_or(&p_hid_ctx->state_flags, 1u << flag));
+}
+
+/**
+ * @brief Clear one of the HID internal state flags.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ * @param[in] flag Flag to clear.
+ */
+static inline void app_usbd_hid_state_flag_clr(app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_hid_state_flag_t flag)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&p_hid_ctx->state_flags, ~(1u << flag)));
+}
+
+
+/**
+ * @brief Test one of the HID internal state flags.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ * @param[in] flag Flag to test.
+ *
+ * @retval true Flag is set.
+ * @retval false Flag is not set.
+ */
+static inline bool app_usbd_hid_state_flag_test(app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_hid_state_flag_t flag)
+{
+ return ((p_hid_ctx->state_flags >> flag) & 1) == 1;
+}
+
+/**
+ * @brief Checks whether HID endpoint transfer required.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ *
+ * @retval true Input endpoint transfer required.
+ * @retval false Transfer in progress or not allowed.
+ */
+static inline bool app_usbd_hid_trans_required(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ if (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED) != 0)
+ {
+ UNUSED_RETURN_VALUE(app_usbd_wakeup_req());
+ return false;
+ }
+
+ return app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS) == 0;
+}
+
+/**
+ * @brief Validates internal hid state.
+ *
+ * HID Mouse has to receive some USBD events before functions from this module could be used.
+ *
+ * @param[in] p_hid_ctx Internal hid context.
+ *
+ * @retval true State is valid.
+ * @retval false State is invalid.
+ */
+static inline bool app_usbd_hid_state_valid(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ /*Check whether internal flags allow to enable mouse*/
+ if ((app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED) == 0) ||
+ (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED) == 0))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * @brief HID generic event handler.
+ *
+ * This handler should process every class event after specific class handler.
+ * This approach allow to handle some events in the same way in all HID sub-classes.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in] p_hid_ctx HID context.
+ * @param[in] p_event Complex event structure.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event);
+
+
+/**
+ * @brief Returns IN report buffer.
+ *
+ * @param[in] p_hinst HID class instance.
+ *
+ * @return Report buffer handle or NULL if report doesn't exist.
+ */
+app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst);
+
+/**
+ * @brief Returns OUT report buffer.
+ *
+ * Output reports are handled in interrupt handler so only one buffer is required. Buffer returned by
+ * this function has predefined size, which should be equal (maximum OUTPUT report size + 1). To receive
+ * OUT report this function should be called on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event.
+ *
+ * @param[in] p_hinst HID class instance.
+ *
+ * @return Report buffer handle or NULL if report doesn't exist.
+ */
+static inline app_usbd_hid_report_buffer_t const *
+app_usbd_hid_rep_buff_out_get(app_usbd_hid_inst_t const * p_hinst)
+{
+ ASSERT(p_hinst);
+ return p_hinst->p_rep_buffer_out;
+}
+
+/**
+ * @brief Auxiliary function to access to HID IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t app_usbd_hid_epin_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access to HID generic OUT endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return OUT endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t app_usbd_hid_epout_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h
new file mode 100644
index 0000000..9fc3486
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h
@@ -0,0 +1,281 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_TYPES_H__
+#define APP_USBD_HID_TYPES_H__
+
+#include <stdint.h>
+
+#include "app_usbd_types.h"
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_hid_types USB HID class types
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types and definitions used by HID modules.
+ * @{
+ */
+
+/**
+ * @brief HID class definition in interface descriptor.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_HID_CLASS 0x03
+
+/**
+ * @brief HID subclass definition.
+ *
+ * @see HID 1.11 specification: Chapter 4.2 Subclass.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ * */
+typedef enum {
+ APP_USBD_HID_SUBCLASS_NONE = 0x00, /**< Undefined subclass. */
+ APP_USBD_HID_SUBCLASS_BOOT = 0x01, /**< Boot subclass. */
+} app_usbd_hid_subclass_t;
+
+/**
+ * @brief HID protocol types defined by specification.
+ *
+ * Value need to be filled in interface descriptor.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ */
+typedef enum {
+ APP_USBD_HID_PROTO_GENERIC = 0x00, /**< GENERIC protocol. */
+ APP_USBD_HID_PROTO_KEYBOARD = 0x01, /**< KEYBOARD protocol. */
+ APP_USBD_HID_PROTO_MOUSE = 0x02, /**< MOUSE protocol. */
+ APP_USBD_HID_PROTO_MULTITOUCH = 0x03, /**< MULTITOUCH protocol. */
+} app_usbd_hid_protocol_t;
+
+
+/**
+ * @brief HID country code ID.
+ *
+ * Look into @ref app_usbd_hid_descriptor_t::bCountryCode.
+ */
+typedef enum {
+ APP_USBD_HID_COUNTRY_NOT_SUPPORTED = 0 , /**< NOT_SUPPORTED */
+ APP_USBD_HID_COUNTRY_ARABIC = 1 , /**< ARABIC */
+ APP_USBD_HID_COUNTRY_BELGIAN = 2 , /**< BELGIAN */
+ APP_USBD_HID_COUNTRY_CANADIAN_BILINGUAL= 3 , /**< CANADIAN_BILINGUAL */
+ APP_USBD_HID_COUNTRY_CANADIAN_FRENCH = 4 , /**< CANADIAN_FRENCH */
+ APP_USBD_HID_COUNTRY_CZECH_REPUBLIC = 5 , /**< CZECH_REPUBLIC */
+ APP_USBD_HID_COUNTRY_DANISH = 6 , /**< DANISH */
+ APP_USBD_HID_COUNTRY_FINNISH = 7 , /**< FINNISH */
+ APP_USBD_HID_COUNTRY_FRENCH = 8 , /**< FRENCH */
+ APP_USBD_HID_COUNTRY_GERMAN = 9 , /**< GERMAN */
+ APP_USBD_HID_COUNTRY_GREEK = 10, /**< GREEK */
+ APP_USBD_HID_COUNTRY_HEBREW = 11, /**< HEBREW */
+ APP_USBD_HID_COUNTRY_HUNGARY = 12, /**< HUNGARY */
+ APP_USBD_HID_COUNTRY_INTERNATIONAL_ISO = 13, /**< INTERNATIONAL_ISO */
+ APP_USBD_HID_COUNTRY_ITALIAN = 14, /**< ITALIAN */
+ APP_USBD_HID_COUNTRY_JAPAN_KATAKANA = 15, /**< JAPAN_KATAKANA */
+ APP_USBD_HID_COUNTRY_KOREAN = 16, /**< KOREAN */
+ APP_USBD_HID_COUNTRY_LATIN_AMERICAN = 17, /**< LATIN_AMERICAN */
+ APP_USBD_HID_COUNTRY_NETHERLANDS_DUTCH = 18, /**< NETHERLANDS_DUTCH */
+ APP_USBD_HID_COUNTRY_NORWEGIAN = 19, /**< NORWEGIAN */
+ APP_USBD_HID_COUNTRY_PERSIAN_FARSI = 20, /**< PERSIAN_FARSI */
+ APP_USBD_HID_COUNTRY_POLAND = 21, /**< POLAND */
+ APP_USBD_HID_COUNTRY_PORTUGUESE = 22, /**< PORTUGUESE */
+ APP_USBD_HID_COUNTRY_RUSSIA = 23, /**< RUSSIA */
+ APP_USBD_HID_COUNTRY_SLOVAKIA = 24, /**< SLOVAKIA */
+ APP_USBD_HID_COUNTRY_SPANISH = 25, /**< SPANISH */
+ APP_USBD_HID_COUNTRY_SWEDISH = 26, /**< SWEDISH */
+ APP_USBD_HID_COUNTRY_SWISS_FRENCH = 27, /**< SWISS_FRENCH */
+ APP_USBD_HID_COUNTRY_SWISS_GERMAN = 28, /**< SWISS_GERMAN */
+ APP_USBD_HID_COUNTRY_SWITZERLAND = 29, /**< SWITZERLAND */
+ APP_USBD_HID_COUNTRY_TAIWAN = 30, /**< TAIWAN */
+ APP_USBD_HID_COUNTRY_TURKISH_Q = 31, /**< TURKISH_Q */
+ APP_USBD_HID_COUNTRY_UK = 32, /**< UK */
+ APP_USBD_HID_COUNTRY_US = 33, /**< US */
+ APP_USBD_HID_COUNTRY_YUGOSLAVIA = 34, /**< YUGOSLAVIA */
+ APP_USBD_HID_COUNTRY_TURKISH_F = 35, /**< TURKISH_F */
+} app_usbd_hid_country_code_t;
+
+/**
+ * @brief HID descriptor types.
+ *
+ * @ref app_usbd_hid_descriptor_t::bRDescriptorType
+ */
+typedef enum {
+ APP_USBD_HID_DESCRIPTOR_HID = 0x21, /**< HID descriptor. */
+ APP_USBD_HID_DESCRIPTOR_REPORT = 0x22, /**< REPORT descriptor. */
+ APP_USBD_HID_DESCRIPTOR_PHYSICAL = 0x23, /**< PHYSICAL descriptor. */
+} app_usbd_hid_descriptor_type_t;
+
+#pragma pack(push, 1)
+
+/**
+ * @brief HID report descriptor entry at the end of HID descriptor.
+ *
+ * @param size Report descriptor size.
+ */
+#define APP_USBD_HID_REPORT_ITEM(size) \
+ APP_USBD_HID_DESCRIPTOR_REPORT, ((size) & 0xFF), ((size) / 256)
+
+
+/**
+ * @brief HID physical descriptor entry at the end of HID descriptor.
+ *
+ * @param size Physical descriptor size.
+ */
+#define APP_USBD_HID_PHYSICAL_ITEM(size) \
+ APP_USBD_HID_DESCRIPTOR_PHYSICAL, ((size) & 0xFF), ((size) / 256)
+
+
+/**
+ * @brief HID descriptor, binary layout.
+ */
+typedef union {
+ struct {
+ uint8_t bLength; //!< Length of descriptor.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_HID_DESCRIPTOR_HID.
+ uint16_t bcdHID; //!< HID release number (BCD format, little endian).
+ uint8_t bCountryCode; //!< Country code.
+ uint8_t bNumDescriptors; //!< Number of class descriptors.
+ struct {
+ uint8_t bRDescriptorType; //!< Class descriptor type.
+ uint16_t wDescriptorLength; //!< Class descriptor length (little endian).
+ } reports[];
+ } raw;
+} app_usbd_hid_descriptor_t;
+
+#pragma pack(pop)
+
+
+/**
+ * @brief HID requests defined by specification.
+ */
+typedef enum {
+ APP_USBD_HID_REQ_GET_REPORT = 0x01, /**< REPORT: device -> host (required). */
+ APP_USBD_HID_REQ_GET_IDLE = 0x02, /**< IDLE: device -> host (not required). */
+ APP_USBD_HID_REQ_GET_PROTOCOL = 0x03, /**< PROTOCOL: device -> host (required for boot protocol). */
+ APP_USBD_HID_REQ_SET_REPORT = 0x09, /**< REPORT: host -> device (not required). */
+ APP_USBD_HID_REQ_SET_IDLE = 0x0A, /**< IDLE: no data stage (required for boot protocol). */
+ APP_USBD_HID_REQ_SET_PROTOCOL = 0x0B, /**< PROTOCOL: no data stage(required for boot protocol). */
+} app_usbd_hid_req_t;
+
+/**
+ * @brief HID report type.
+ */
+typedef enum {
+ APP_USBD_HID_REPORT_TYPE_INPUT = 0x01,/**< INPUT report type */
+ APP_USBD_HID_REPORT_TYPE_OUTPUT = 0x02,/**< OUTPUT report type */
+ APP_USBD_HID_REPORT_TYPE_FEATURE = 0x03,/**< FEATURE report type */
+} app_usbd_hid_report_type_t;
+
+
+/**
+ * @brief Hid version BCD value definition
+ *
+ * The version of the HID descriptors used.
+ */
+#define APP_USBD_HID_BCD_VER APP_USBD_BCD_VER_MAKE(1, 11)
+
+/**
+ * @brief HID version BCD value definition distributed into bytes
+ *
+ * This is a value written directly into @ref app_usbd_hid_descriptor_t::bcdHID.
+ * @sa APP_USBD_HID_BCD_VER
+ */
+#define APP_USBD_HID_BCD_VER_BYTES LSB_16(APP_USBD_HID_BCD_VER), MSB_16(APP_USBD_HID_BCD_VER)
+
+/**
+ * @brief Initializer of interface descriptor for HID classes.
+ *
+ * @param interface_number Interface number.
+ * @param endpoints_num Number of endpoints.
+ * @param subclass Subclass type @ref app_usbd_hid_subclass_t.
+ * @param protocol Protocol type @ref app_usbd_hid_protocol_t.
+ */
+#define APP_USBD_HID_INTERFACE_DSC(interface_number, endpoints_num, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ endpoints_num, \
+ /*.bInterfaceClass = */ APP_USBD_HID_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of HID descriptor for HID classes.
+ *
+ * @param ... Report/physical item list.
+ */
+#define APP_USBD_HID_HID_DSC(...) \
+ /*.bLength = */ sizeof(app_usbd_hid_descriptor_t) + 3 * (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_HID_DESCRIPTOR_HID, \
+ /*.bcdHID = */ APP_USBD_HID_BCD_VER_BYTES, \
+ /*.bCountryCode = */ APP_USBD_HID_COUNTRY_NOT_SUPPORTED, \
+ /*.bNumDescriptors = */ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bRDescriptorType = */ APP_USBD_HID_REPORT_ITEM(sizeof(GET_VA_ARG_1_(__VA_ARGS__))), \
+ /*.wDescriptorLength = */
+
+/**
+ * @brief Initializer of endpoint descriptor for HID classes.
+ *
+ * @param endpoint Endpoint number.
+ * @param ep_size Endpoint size.
+ * @param ep_interval Endpoint interval (milliseconds).
+ */
+#define APP_USBD_HID_EP_DSC(endpoint, ep_size, ep_interval) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ ep_interval, \
+
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c
new file mode 100644
index 0000000..61dea15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c
@@ -0,0 +1,506 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID_GENERIC)
+
+#include <string.h>
+#include "app_usbd_hid_generic.h"
+#include "app_util_platform.h"
+
+
+/**
+ * @ingroup app_usbd_hid_generic
+ *
+ * Module with types, definitions and API used by HID generic.
+ * @{
+ */
+
+/**
+ * @brief Auxiliary function to access HID generic context data.
+ *
+ * @param[in] p_generic HID generic instance.
+ *
+ * @return HID generic class instance data context.
+ */
+static inline app_usbd_hid_generic_ctx_t *
+hid_generic_ctx_get(app_usbd_hid_generic_t const * p_generic)
+{
+ ASSERT(p_generic != NULL);
+ ASSERT(p_generic->specific.p_data != NULL);
+ return &p_generic->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access HID generic instance data.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return HID generic class instance data.
+ */
+static inline app_usbd_hid_generic_t const *
+hid_generic_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_hid_generic_t const *)p_inst;
+}
+
+
+/**
+ * @brief Returns report ID buffer descriptor.
+ *
+ * @param[in] p_generic Internal HID generic context.
+ *
+ * @return HID report buffer.
+ */
+static inline app_usbd_hid_report_buffer_t *
+hid_generic_rep_buffer_get(app_usbd_hid_generic_t const * p_generic)
+{
+ ASSERT(p_generic != NULL);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return app_usbd_hid_rep_buff_in_get(p_hinst);
+}
+
+
+/**
+ * @brief Auxiliary function to prepare report transfer buffer to next transfer.
+ *
+ * @param[in] p_generic HID generic instance.
+ *
+ * @retval true Next transfer required.
+ * @retval false Next transfer not required.
+ */
+static inline bool hid_generic_transfer_next(app_usbd_hid_generic_t const * p_generic)
+{
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+
+ return !nrf_queue_is_empty(p_rep_in_queue);
+}
+
+
+/**
+ * @brief Triggers IN endpoint transfer.
+ *
+ * @param[in] p_generic HID generic instance.
+ *
+ * @return Standard error code.
+ */
+static inline ret_code_t hid_generic_transfer_set(app_usbd_hid_generic_t const * p_generic)
+{
+ app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_generic;
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst);
+
+ app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+
+ if (!hid_generic_transfer_next(p_generic))
+ {
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_report_buffer_t * p_rep_buff = hid_generic_rep_buffer_get(p_generic);
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+
+ ret_code_t ret = nrf_queue_pop(p_rep_in_queue, p_rep_buff);
+ ASSERT(ret == NRF_SUCCESS);
+
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buff->p_buff, p_rep_buff->size);
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(ep_addr, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_hid_state_flag_set(&p_generic_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+ret_code_t app_usbd_hid_generic_in_report_set(app_usbd_hid_generic_t const * p_generic,
+ const void * p_buff,
+ size_t size)
+{
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+ const app_usbd_hid_report_buffer_t rep_buff = {
+ .p_buff = (void *)p_buff,
+ .size = size,
+ };
+
+ if (nrf_queue_push(p_rep_in_queue, &rep_buff) != NRF_SUCCESS)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ ret_code_t ret = NRF_SUCCESS;
+ if (app_usbd_hid_trans_required(&p_generic_ctx->hid_ctx))
+ {
+ ret = hid_generic_transfer_set(p_generic);
+ }
+
+ return ret;
+}
+
+
+const void * app_usbd_hid_generic_in_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ *p_size = p_hinst->p_rep_buffer_in->size;
+ return p_hinst->p_rep_buffer_in->p_buff;
+}
+
+
+const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ *p_size = p_hinst->p_rep_buffer_out->size;
+ return p_hinst->p_rep_buffer_out->p_buff;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_get_report
+ */
+static ret_code_t hid_generic_on_get_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_generic_t const * p_hinst = hid_generic_get(p_inst);
+ uint8_t const * p_rep_buffer = NULL;
+ size_t buffer_size = 0;
+
+ if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_INPUT)
+ {
+ p_rep_buffer = app_usbd_hid_generic_in_report_get(p_hinst, &buffer_size);
+ }
+ else if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_OUTPUT)
+ {
+ p_rep_buffer = app_usbd_hid_generic_out_report_get(p_hinst, &buffer_size);
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer, buffer_size);
+}
+
+
+static ret_code_t hid_generic_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status,
+ void * p_context)
+{
+ app_usbd_hid_user_ev_handler_t handler;
+ app_usbd_hid_generic_t const * p_generic = (app_usbd_hid_generic_t const *)p_context;
+
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ handler = p_generic->specific.inst.hid_inst.user_event_handler;
+ handler((app_usbd_class_inst_t const *)p_generic,
+ APP_USBD_HID_USER_EVT_OUT_REPORT_READY);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_set_report
+ */
+static ret_code_t hid_generic_on_set_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+
+ /*Request setup data*/
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst);
+
+ p_rep_buff->p_buff[0] = p_setup_ev->setup.wValue.lb;
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = hid_generic_on_set_report_data_cb,
+ .p_context = (void *)p_generic
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::ep_transfer_in
+ */
+static ret_code_t hid_generic_ep_transfer_in(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+
+ if (nrf_queue_is_empty(p_rep_in_queue))
+ {
+ app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ return NRF_SUCCESS;
+ }
+
+ /* Get next report to send */
+ return hid_generic_transfer_set((app_usbd_hid_generic_t const *)p_inst);
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::ep_transfer_out
+ */
+static ret_code_t hid_generic_ep_transfer_out(app_usbd_class_inst_t const * p_inst)
+{
+
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epout_addr_get(p_inst);
+
+ /*Request setup data*/
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst);
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff, p_rep_buff->size);
+
+ return app_usbd_ep_transfer(ep_addr, &transfer);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::event_handler
+ */
+static ret_code_t hid_generic_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+ app_usbd_hid_ctx_t * p_hid_ctx = &p_generic_ctx->hid_ctx;
+
+ /*Try handle event by generic HID event handler*/
+ return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+}
+
+
+static uint8_t hid_generic_get_class_descriptors_count(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->subclass_desc_count;
+}
+
+
+static app_usbd_descriptor_t hid_generic_get_class_descriptors_type(
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->type;
+}
+
+
+static size_t hid_generic_get_class_descriptors_length(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->size;
+}
+
+
+static uint8_t hid_generic_get_class_descriptors_data(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num,
+ uint32_t cur_byte)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->p_data[cur_byte];
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::feed_descriptors
+ */
+static bool hid_generic_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_CLASS); // bInterfaceClass = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_generic->specific.inst.hid_inst.subclass_boot); // bInterfaceSubclass (Boot Interface)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_generic->specific.inst.hid_inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HID DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_DESCRIPTOR_HID); // bDescriptorType = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(APP_USBD_HID_BCD_VER)); // bcdHID LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(APP_USBD_HID_BCD_VER)); // bcdHID MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_COUNTRY_NOT_SUPPORTED); // bCountryCode
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_generic_get_class_descriptors_count(p_inst)); // bNumDescriptors
+
+ static uint8_t class_desc_cnt = 0;
+ class_desc_cnt = hid_generic_get_class_descriptors_count(p_inst);
+ static uint8_t j = 0;
+ static uint16_t class_desc_len = 0;
+
+ for (j = 0; j < class_desc_cnt; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_generic_get_class_descriptors_type(p_inst, j)); // bDescriptorType
+
+ class_desc_len = hid_generic_get_class_descriptors_length(p_inst, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(class_desc_len)); // wDescriptorLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(class_desc_len)); // wDescriptorLength MSB
+ }
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ for (j = 0; j < endpoints; j++)
+ {
+ /* ENDPOINT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLengths
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ }
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::feed_subclass_descriptor
+ */
+
+static bool hid_generic_feed_subclass_descriptor(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size,
+ uint8_t index)
+{
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* PHYSICAL AND REPORT DESCRIPTORS */
+ static uint32_t cur_byte = 0;
+ static size_t sub_desc_size = 0;
+ sub_desc_size = hid_generic_get_class_descriptors_length(p_inst, index);
+
+ for (cur_byte = 0; cur_byte < sub_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_generic_get_class_descriptors_data(p_inst, index,
+ cur_byte));
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+
+/** @} */
+
+const app_usbd_hid_methods_t app_usbd_hid_generic_methods = {
+ .on_get_report = hid_generic_on_get_report,
+ .on_set_report = hid_generic_on_set_report,
+ .ep_transfer_in = hid_generic_ep_transfer_in,
+ .ep_transfer_out = hid_generic_ep_transfer_out,
+ .feed_subclass_descriptor = hid_generic_feed_subclass_descriptor,
+};
+
+const app_usbd_class_methods_t app_usbd_generic_class_methods = {
+ .event_handler = hid_generic_event_handler,
+ .feed_descriptors = hid_generic_feed_descriptors,
+};
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID_GENERIC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h
new file mode 100644
index 0000000..3642b16
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_GENERIC_H__
+#define APP_USBD_HID_GENERIC_H__
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd_hid.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+#include "app_usbd_hid_generic_desc.h"
+#include "app_usbd_hid_generic_internal.h"
+
+/**
+ * @defgroup app_usbd_hid_generic USB HID generic
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic class.
+ * @{
+ */
+
+
+#ifdef DOXYGEN
+/**
+ * @brief HID generic class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_hid_generic_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_hid_generic, \
+ APP_USBD_HID_GENERIC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \
+ APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+/**
+ * @brief Global definition of app_usbd_hid_generic_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param interface_number Unique interface index.
+ * @param user_ev_handler User event handler (optional).
+ * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t).
+ * @param subclass_descriptors HID subclass descriptors.
+ * @param report_in_queue_size IN report queue size.
+ * @param report_out_maxsize Maximum output report size.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ * @param protocol HID protocol. (@ref app_usbd_hid_protocol_t)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL.
+ *
+ * Example class definition:
+ * @code
+
+ APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(mouse_desc,APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(2));
+
+ static const app_usbd_hid_subclass_desc_t * reps[] = {&mouse_desc};
+
+ #define ENDPOINT_LIST \
+ ( \
+ NRF_DRV_USBD_EPIN1 \
+ )
+
+ #define REPORT_COUNT 1
+ #define REPORT_OUT_MAXSIZE 0
+
+ APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_generic,
+ 0,
+ hid_user_ev_handler,
+ ENDPOINT_LIST(),
+ reps,
+ REPORT_IN_QUEUE_SIZE,
+ REPORT_OUT_MAXSIZE,
+ APP_USBD_HID_SUBCLASS_BOOT,
+ APP_USBD_HID_PROTO_MOUSE);
+ @endcode
+ *
+ */
+#define APP_USBD_HID_GENERIC_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ subclass_descriptors, \
+ report_in_queue_size, \
+ report_out_maxsize, \
+ subclass_boot, \
+ protocol) \
+ APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ subclass_descriptors, \
+ report_in_queue_size, \
+ report_out_maxsize, \
+ subclass_boot, \
+ protocol)
+
+
+/**
+ * @brief Helper function to get class instance from HID generic class.
+ *
+ * @param[in] p_generic HID generic class instance.
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_hid_generic_class_inst_get(app_usbd_hid_generic_t const * p_generic)
+{
+ return &p_generic->base;
+}
+
+/**
+ * @brief Helper function to get HID generic from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return HID generic class handle.
+ */
+static inline app_usbd_hid_generic_t const *
+app_usbd_hid_generic_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_hid_generic_t const *)p_inst;
+}
+
+/**
+ * @brief New IN report trigger
+ *
+ *
+ * @param[in] p_generic HID generic class instance.
+ * @param[in] p_buff Report buffer.
+ * @param[in] size Report size.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_generic_in_report_set(app_usbd_hid_generic_t const * p_generic,
+ const void * p_buff,
+ size_t size);
+
+/**
+ * @brief Returns last successful transfered IN report.
+ *
+ * @note Use this call only on @ref APP_USBD_HID_USER_EVT_IN_REPORT_DONE event.
+ *
+ * @param[in] p_generic HID generic class instance.
+ * @param[out] p_size Last transfered IN report size.
+ *
+ * @return Last transfered report ID.
+ */
+const void * app_usbd_hid_generic_in_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size);
+
+/**
+ * @brief Returns last successful transfered OUT report.
+ *
+ * @warning Use this call only on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event.
+ *
+ * @param[in] p_generic HID generic class instance.
+ * @param[out] p_size Last transfered OUT report size.
+ *
+ * @return Last transfered OUT report.
+ */
+const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_GENERIC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h
new file mode 100644
index 0000000..1ff4487
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_GENERIC_DESC_H__
+#define APP_USBD_HID_GENERIC_DESC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_hid_generic_desc USB HID generic descriptors
+ * @ingroup app_usbd_hid_generic
+ *
+ * @brief @tagAPI52840 Module with descriptors used by the HID generic class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for HID generic class.
+ *
+ * @param interface_number Interface number.
+ * @param endpoints_num Number of endpoints.
+ * @param subclass Subclass type @ref app_usbd_hid_subclass_t.
+ * @param protocol Protocol type @ref app_usbd_hid_protocol_t.
+ */
+#define APP_USBD_HID_GENERIC_INTERFACE_DSC(interface_number, \
+ endpoints_num, \
+ subclass, \
+ protocol) \
+ APP_USBD_HID_INTERFACE_DSC(interface_number, \
+ endpoints_num, \
+ subclass, \
+ protocol) \
+
+/**
+ * @brief Initializer of HID descriptor for HID generic class.
+ *
+ * @param ... Report descriptor item.
+ */
+#define APP_USBD_HID_GENERIC_HID_DSC(...) \
+ APP_USBD_HID_HID_DSC(__VA_ARGS__)
+/**
+ * @brief Initializer of endpoint descriptor for HID generic class.
+ *
+ * @param endpoint Endpoint number.
+ */
+#define APP_USBD_HID_GENERIC_EP_DSC(endpoint) \
+ APP_USBD_HID_EP_DSC(endpoint, NRF_DRV_USBD_EPSIZE, 1)
+
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_GENERIC_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h
new file mode 100644
index 0000000..4844fde
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h
@@ -0,0 +1,186 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_GENERIC_INTERNAL_H__
+#define APP_USBD_HID_GENERIC_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "app_usbd_hid.h"
+#include "nrf_queue.h"
+
+/**
+ * @defgroup app_usbd_hid_generic_internal USB HID generic internals
+ * @ingroup app_usbd_hid_generic
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic protocol.
+ * @{
+ */
+
+
+/**
+ * @brief Forward declaration of HID generic class type.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_hid_generic);
+
+/**
+ * @brief HID generic part of class instance data.
+ *
+ */
+typedef struct {
+ app_usbd_hid_inst_t hid_inst; //!< HID instance data.
+ nrf_queue_t const * p_rep_in_queue; //!< Input report queue.
+} app_usbd_hid_generic_inst_t;
+
+/**
+ * @brief HID generic context
+ *
+ */
+typedef struct {
+ app_usbd_hid_ctx_t hid_ctx; //!< HID class context.
+} app_usbd_hid_generic_ctx_t;
+
+
+/**
+ * @brief HID generic configuration macro.
+ *
+ * Used by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF.
+ *
+ * @param iface Interface number.
+ * @param endpoints Endpoint list.
+ */
+#define APP_USBD_HID_GENERIC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints)))
+
+
+/**
+ * @brief Specific class constant data for HID generic class.
+ */
+#define APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC app_usbd_hid_generic_inst_t inst;
+
+/**
+ * @brief Specific class data for HID generic class.
+ */
+#define APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC app_usbd_hid_generic_ctx_t ctx;
+
+/**
+ * @brief Configure internal part of HID generic instance.
+ *
+ * @param report_buff_in Input report buffers array.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler User event handler.
+ * @param in_report_queue IN report queue.
+ * @param subclass_descriptors HID subclass descriptors.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ * @param protocol HID protocol. (@ref app_usbd_hid_protocol_t)
+ */
+#define APP_USBD_HID_GENERIC_INST_CONFIG(report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ in_report_queue, \
+ subclass_descriptors, \
+ subclass_boot, \
+ protocol) \
+ .inst = { \
+ .hid_inst = APP_USBD_HID_INST_CONFIG(subclass_descriptors, \
+ subclass_boot, \
+ protocol, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ &app_usbd_hid_generic_methods), \
+ .p_rep_in_queue = in_report_queue, \
+ }
+
+/**
+ * @brief Public HID generic interface.
+ */
+extern const app_usbd_hid_methods_t app_usbd_hid_generic_methods;
+
+/**
+ * @brief Public HID generic class interface.
+ */
+extern const app_usbd_class_methods_t app_usbd_generic_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_hid_generic_t class.
+ *
+ * @ref APP_USBD_HID_GENERIC_GLOBAL_DEF
+ */
+#define APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ subclass_descriptors, \
+ report_in_queue_size, \
+ report_out_maxsize, \
+ subclass_boot, \
+ protocol) \
+ static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in); \
+ APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), \
+ report_out_maxsize + 1); \
+ NRF_QUEUE_DEF(app_usbd_hid_report_buffer_t, \
+ instance_name##_queue, \
+ report_in_queue_size, \
+ NRF_QUEUE_MODE_OVERFLOW); \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_hid_generic, \
+ &app_usbd_generic_class_methods, \
+ APP_USBD_HID_GENERIC_CONFIG(interface_number, endpoint_list), \
+ (APP_USBD_HID_GENERIC_INST_CONFIG(&CONCAT_2(instance_name, _in), \
+ &CONCAT_2(instance_name, _out), \
+ user_ev_handler, \
+ &instance_name##_queue, \
+ subclass_descriptors, \
+ subclass_boot, \
+ protocol)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_GENERIC_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c
new file mode 100644
index 0000000..53d03f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c
@@ -0,0 +1,557 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID_KBD)
+
+#include <string.h>
+#include "app_usbd_hid_kbd.h"
+#include "app_util_platform.h"
+
+
+/**
+ * @defgroup app_usbd_hid_kbd_internals USB HID keyboard internals
+ * @{
+ * @ingroup app_usbd_hid_kbd
+ * @internal
+ */
+
+STATIC_ASSERT(sizeof(app_usbd_hid_descriptor_t) == 6);
+
+/**
+ * @brief Auxiliary function to access HID keyboard context data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID keyboard instance data context.
+ */
+static inline app_usbd_hid_kbd_ctx_t * hid_kbd_ctx_get(app_usbd_hid_kbd_t const * p_kbd)
+{
+ ASSERT(p_kbd != NULL);
+ ASSERT(p_kbd->specific.p_data != NULL);
+ return &p_kbd->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access HID keyboard instance data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID keyboard instance data.
+ */
+static inline app_usbd_hid_kbd_t const * hid_kbd_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_hid_kbd_t const *)p_inst;
+}
+
+
+/**
+ * @brief Returns keyboard report buffer handle.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @return HID report buffer.
+ */
+static inline
+app_usbd_hid_report_buffer_t const * hid_kbd_rep_buffer_get(app_usbd_hid_kbd_t const * p_kbd)
+{
+ ASSERT(p_kbd != NULL);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst);
+
+ p_rep_buff->p_buff = p_kbd_ctx->report_buff;
+ p_rep_buff->size = sizeof(p_kbd_ctx->report_buff);
+
+ /*Keyboard has only one report input/output report buffer */
+ return p_rep_buff;
+}
+
+
+/**
+ * @brief Auxiliary function to prepare report transfer buffer to next transfer.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @retval true Next transfer is required.
+ * @retval false Next transfer is not required.
+ */
+static inline bool hid_kbd_transfer_next(app_usbd_hid_kbd_t const * p_kbd)
+{
+ /*Send report only when state has changed*/
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd);
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+
+ if (memcmp(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size))
+ {
+ memcpy(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size);
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * @brief Triggers IN endpoint transfer.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @return Standard error code.
+ */
+static inline ret_code_t hid_kbd_transfer_set(app_usbd_hid_kbd_t const * p_kbd)
+{
+ app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_kbd;
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst);
+
+ app_usbd_hid_state_flag_clr(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+
+ if (!hid_kbd_transfer_next(p_kbd))
+ {
+ /* Transfer buffer hasn't changed since last transfer. No need to setup
+ * next transfer.
+ * */
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd);
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(ep_addr, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_hid_state_flag_set(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_modifier_t modifier,
+ bool state)
+{
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ bool actual_state = (p_kbd_ctx->rep.modifier & modifier) != 0;
+
+ if (actual_state == state)
+ {
+ /*Modifier has already the same state*/
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx);
+
+ if (state)
+ {
+ p_kbd_ctx->rep.modifier |= modifier;
+ }
+ else
+ {
+ p_kbd_ctx->rep.modifier &= ~modifier;
+ }
+ app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_kbd_transfer_set(p_kbd);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_codes_t key,
+ bool press)
+{
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ uint8_t * destination = NULL;
+
+ if (press)
+ {
+ for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i)
+ {
+ if (p_kbd_ctx->rep.key_table[i] == key)
+ {
+ /*Already pressed*/
+ return NRF_SUCCESS;
+ }
+
+ if ((destination == NULL) && (p_kbd_ctx->rep.key_table[i] == 0))
+ {
+ destination = &p_kbd_ctx->rep.key_table[i];
+ }
+ }
+
+ if (destination == NULL)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+ else
+ {
+ /*Find if key is pressed*/
+ for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i)
+ {
+ if (p_kbd_ctx->rep.key_table[i] == key)
+ {
+ destination = &p_kbd_ctx->rep.key_table[i];
+ break;
+ }
+ }
+
+ if (destination == NULL)
+ {
+ /*Key hasn't been pressed*/
+ return NRF_SUCCESS;
+ }
+ }
+
+ /*Save destination*/
+ app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx);
+ *destination = press ? key : 0;
+ app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_kbd_transfer_set(p_kbd);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_led_t led)
+{
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+
+ return (p_kbd_ctx->leds_state & led) != 0;
+}
+
+const void * app_usbd_hid_kbd_in_report_get(app_usbd_hid_kbd_t const * p_kbd,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_kinst = &p_kbd->specific.inst.hid_inst;
+ *p_size = p_kinst->p_rep_buffer_in->size;
+ return p_kinst->p_rep_buffer_in->p_buff;
+}
+
+const void * app_usbd_hid_kbd_out_report_get(app_usbd_hid_kbd_t const * p_kbd,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_kinst = &p_kbd->specific.inst.hid_inst;
+ *p_size = p_kinst->p_rep_buffer_out->size;
+ return p_kinst->p_rep_buffer_out->p_buff;
+}
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_get_report
+ */
+static ret_code_t hid_kbd_on_get_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_kbd_t const * p_kinst = hid_kbd_get(p_inst);
+ uint8_t const * p_rep_buffer = NULL;
+ size_t buffer_size = 0;
+
+ if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_INPUT)
+ {
+ p_rep_buffer = app_usbd_hid_kbd_in_report_get(p_kinst, &buffer_size);
+ }
+ else if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_OUTPUT)
+ {
+ p_rep_buffer = app_usbd_hid_kbd_out_report_get(p_kinst, &buffer_size);
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ /* Return LEDs state (only the second byte) */
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer + 1, buffer_size - 1);
+}
+
+
+static ret_code_t hid_kbd_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ app_usbd_hid_kbd_t const * p_kbd = p_context;
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst);
+
+ /*Update LEDs state*/
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ p_kbd_ctx->leds_state = p_rep_buff->p_buff[1];
+
+ app_usbd_hid_user_ev_handler_t handler = p_kbd->specific.inst.hid_inst.user_event_handler;
+ handler((app_usbd_class_inst_t const *)(p_kbd), APP_USBD_HID_USER_EVT_OUT_REPORT_READY);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::hid_kbd_on_set_report
+ */
+static ret_code_t hid_kbd_on_set_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+
+ /*Request setup data*/
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst);
+
+ p_rep_buff->p_buff[0] = 0;
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = hid_kbd_on_set_report_data_cb,
+ .p_context = (app_usbd_hid_kbd_t *)p_kbd
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::hid_kbd_ep_transfer_in
+ */
+static ret_code_t hid_kbd_ep_transfer_in(app_usbd_class_inst_t const * p_inst)
+{
+ return hid_kbd_transfer_set((app_usbd_hid_kbd_t const *)p_inst);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::event_handler
+ */
+static ret_code_t hid_kbd_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ app_usbd_hid_ctx_t * p_hid_ctx = &p_kbd_ctx->hid_ctx;
+
+ /*Try handle event by generic HID event handler*/
+ return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+}
+
+
+static uint8_t hid_kbd_get_class_descriptors_count(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->subclass_desc_count;
+}
+
+
+static app_usbd_descriptor_t hid_kbd_get_class_descriptors_type(
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->type;
+}
+
+
+static size_t hid_kbd_get_class_descriptors_length(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->size;
+}
+
+
+static uint8_t hid_kbd_get_class_descriptors_data(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num,
+ uint32_t cur_byte)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->p_data[cur_byte];
+}
+
+
+static bool hid_kbd_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_CLASS); // bInterfaceClass = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_kbd->specific.inst.hid_inst.subclass_boot); // bInterfaceSubclass (Boot Interface)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_kbd->specific.inst.hid_inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HID DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_DESCRIPTOR_HID); // bDescriptorType = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(APP_USBD_HID_BCD_VER)); // bcdHID LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(APP_USBD_HID_BCD_VER)); // bcdHID MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_COUNTRY_NOT_SUPPORTED); // bCountryCode
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_kbd_get_class_descriptors_count(p_inst)); // bNumDescriptors
+
+ static uint8_t class_desc_cnt = 0;
+ class_desc_cnt = hid_kbd_get_class_descriptors_count(p_inst);
+ static uint8_t j = 0;
+ static uint16_t class_desc_len = 0;
+
+ for (j = 0; j < class_desc_cnt; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_kbd_get_class_descriptors_type(p_inst, j)); // bDescriptorType
+
+ class_desc_len = hid_kbd_get_class_descriptors_length(p_inst, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(class_desc_len)); // wDescriptorLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(class_desc_len)); // wDescriptorLength MSB
+ }
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ for (j = 0; j < endpoints; j++)
+ {
+ /* ENDPOINT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLengths
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ }
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+static bool hid_kbd_feed_subclass_descriptor(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size,
+ uint8_t index)
+{
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* PHYSICAL AND REPORT DESCRIPTORS */
+ static uint32_t cur_byte = 0;
+ static size_t sub_desc_size = 0;
+ sub_desc_size = hid_kbd_get_class_descriptors_length(p_inst, index);
+
+ for (cur_byte = 0; cur_byte <= sub_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_kbd_get_class_descriptors_data(p_inst, index, cur_byte));
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/** @} */
+
+const app_usbd_hid_methods_t app_usbd_hid_kbd_methods = {
+ .on_get_report = hid_kbd_on_get_report,
+ .on_set_report = hid_kbd_on_set_report,
+ .ep_transfer_in = hid_kbd_ep_transfer_in,
+ .ep_transfer_out = NULL,
+ .feed_subclass_descriptor = hid_kbd_feed_subclass_descriptor,
+};
+
+const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods = {
+ .event_handler = hid_kbd_event_handler,
+ .feed_descriptors = hid_kbd_feed_descriptors,
+};
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID_KBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h
new file mode 100644
index 0000000..2343829
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h
@@ -0,0 +1,309 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_KBD_H__
+#define APP_USBD_HID_KBD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd_hid.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+#include "app_usbd_hid_kbd_desc.h"
+#include "app_usbd_hid_kbd_internal.h"
+
+
+/**
+ * @defgroup app_usbd_hid_kbd USB HID keyboard
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class.
+ * @{
+ */
+
+/**
+ * @brief HID keyboard codes.
+ */
+typedef enum {
+ APP_USBD_HID_KBD_A = 4, /**<KBD_A code*/
+ APP_USBD_HID_KBD_B = 5, /**<KBD_B code*/
+ APP_USBD_HID_KBD_C = 6, /**<KBD_C code*/
+ APP_USBD_HID_KBD_D = 7, /**<KBD_D code*/
+ APP_USBD_HID_KBD_E = 8, /**<KBD_E code*/
+ APP_USBD_HID_KBD_F = 9, /**<KBD_F code*/
+ APP_USBD_HID_KBD_G = 10, /**<KBD_G code*/
+ APP_USBD_HID_KBD_H = 11, /**<KBD_H code*/
+ APP_USBD_HID_KBD_I = 12, /**<KBD_I code*/
+ APP_USBD_HID_KBD_J = 13, /**<KBD_J code*/
+ APP_USBD_HID_KBD_K = 14, /**<KBD_K code*/
+ APP_USBD_HID_KBD_L = 15, /**<KBD_L code*/
+ APP_USBD_HID_KBD_M = 16, /**<KBD_M code*/
+ APP_USBD_HID_KBD_N = 17, /**<KBD_N code*/
+ APP_USBD_HID_KBD_O = 18, /**<KBD_O code*/
+ APP_USBD_HID_KBD_P = 19, /**<KBD_P code*/
+ APP_USBD_HID_KBD_Q = 20, /**<KBD_Q code*/
+ APP_USBD_HID_KBD_R = 21, /**<KBD_R code*/
+ APP_USBD_HID_KBD_S = 22, /**<KBD_S code*/
+ APP_USBD_HID_KBD_T = 23, /**<KBD_T code*/
+ APP_USBD_HID_KBD_U = 24, /**<KBD_U code*/
+ APP_USBD_HID_KBD_V = 25, /**<KBD_V code*/
+ APP_USBD_HID_KBD_W = 26, /**<KBD_W code*/
+ APP_USBD_HID_KBD_X = 27, /**<KBD_X code*/
+ APP_USBD_HID_KBD_Y = 28, /**<KBD_Y code*/
+ APP_USBD_HID_KBD_Z = 29, /**<KBD_Z code*/
+ APP_USBD_HID_KBD_1 = 30, /**<KBD_1 code*/
+ APP_USBD_HID_KBD_2 = 31, /**<KBD_2 code*/
+ APP_USBD_HID_KBD_3 = 32, /**<KBD_3 code*/
+ APP_USBD_HID_KBD_4 = 33, /**<KBD_4 code*/
+ APP_USBD_HID_KBD_5 = 34, /**<KBD_5 code*/
+ APP_USBD_HID_KBD_6 = 35, /**<KBD_6 code*/
+ APP_USBD_HID_KBD_7 = 36, /**<KBD_7 code*/
+ APP_USBD_HID_KBD_8 = 37, /**<KBD_8 code*/
+ APP_USBD_HID_KBD_9 = 38, /**<KBD_9 code*/
+ APP_USBD_HID_KBD_0 = 39, /**<KBD_0 code*/
+ APP_USBD_HID_KBD_ENTER = 40, /**<KBD_ENTER code*/
+ APP_USBD_HID_KBD_ESCAPE = 41, /**<KBD_ESCAPE code*/
+ APP_USBD_HID_KBD_BACKSPACE = 42, /**<KBD_BACKSPACE code*/
+ APP_USBD_HID_KBD_TAB = 43, /**<KBD_TAB code*/
+ APP_USBD_HID_KBD_SPACEBAR = 44, /**<KBD_SPACEBAR code*/
+ APP_USBD_HID_KBD_UNDERSCORE = 45, /**<KBD_UNDERSCORE code*/
+ APP_USBD_HID_KBD_PLUS = 46, /**<KBD_PLUS code*/
+ APP_USBD_HID_KBD_OPEN_BRACKET = 47, /**<KBD_OPEN_BRACKET code*/
+ APP_USBD_HID_KBD_CLOSE_BRACKET = 48, /**<KBD_CLOSE_BRACKET code*/
+ APP_USBD_HID_KBD_BACKSLASH = 49, /**<KBD_BACKSLASH code*/
+ APP_USBD_HID_KBD_ASH = 50, /**<KBD_ASH code*/
+ APP_USBD_HID_KBD_COLON = 51, /**<KBD_COLON code*/
+ APP_USBD_HID_KBD_QUOTE = 52, /**<KBD_QUOTE code*/
+ APP_USBD_HID_KBD_TILDE = 53, /**<KBD_TILDE code*/
+ APP_USBD_HID_KBD_COMMA = 54, /**<KBD_COMMA code*/
+ APP_USBD_HID_KBD_DOT = 55, /**<KBD_DOT code*/
+ APP_USBD_HID_KBD_SLASH = 56, /**<KBD_SLASH code*/
+ APP_USBD_HID_KBD_CAPS_LOCK = 57, /**<KBD_CAPS_LOCK code*/
+ APP_USBD_HID_KBD_F1 = 58, /**<KBD_F1 code*/
+ APP_USBD_HID_KBD_F2 = 59, /**<KBD_F2 code*/
+ APP_USBD_HID_KBD_F3 = 60, /**<KBD_F3 code*/
+ APP_USBD_HID_KBD_F4 = 61, /**<KBD_F4 code*/
+ APP_USBD_HID_KBD_F5 = 62, /**<KBD_F5 code*/
+ APP_USBD_HID_KBD_F6 = 63, /**<KBD_F6 code*/
+ APP_USBD_HID_KBD_F7 = 64, /**<KBD_F7 code*/
+ APP_USBD_HID_KBD_F8 = 65, /**<KBD_F8 code*/
+ APP_USBD_HID_KBD_F9 = 66, /**<KBD_F9 code*/
+ APP_USBD_HID_KBD_F10 = 67, /**<KBD_F10 code*/
+ APP_USBD_HID_KBD_F11 = 68, /**<KBD_F11 code*/
+ APP_USBD_HID_KBD_F12 = 69, /**<KBD_F12 code*/
+ APP_USBD_HID_KBD_PRINTSCREEN = 70, /**<KBD_PRINTSCREEN code*/
+ APP_USBD_HID_KBD_SCROLL_LOCK = 71, /**<KBD_SCROLL_LOCK code*/
+ APP_USBD_HID_KBD_PAUSE = 72, /**<KBD_PAUSE code*/
+ APP_USBD_HID_KBD_INSERT = 73, /**<KBD_INSERT code*/
+ APP_USBD_HID_KBD_HOME = 74, /**<KBD_HOME code*/
+ APP_USBD_HID_KBD_PAGEUP = 75, /**<KBD_PAGEUP code*/
+ APP_USBD_HID_KBD_DELETE = 76, /**<KBD_DELETE code*/
+ APP_USBD_HID_KBD_END = 77, /**<KBD_END code*/
+ APP_USBD_HID_KBD_PAGEDOWN = 78, /**<KBD_PAGEDOWN code*/
+ APP_USBD_HID_KBD_RIGHT = 79, /**<KBD_RIGHT code*/
+ APP_USBD_HID_KBD_LEFT = 80, /**<KBD_LEFT code*/
+ APP_USBD_HID_KBD_DOWN = 81, /**<KBD_DOWN code*/
+ APP_USBD_HID_KBD_UP = 82, /**<KBD_UP code*/
+ APP_USBD_HID_KBD_KEYPAD_NUM_LOCK = 83, /**<KBD_KEYPAD_NUM_LOCK code*/
+ APP_USBD_HID_KBD_KEYPAD_DIVIDE = 84, /**<KBD_KEYPAD_DIVIDE code*/
+ APP_USBD_HID_KBD_KEYPAD_AT = 85, /**<KBD_KEYPAD_AT code*/
+ APP_USBD_HID_KBD_KEYPAD_MULTIPLY = 85, /**<KBD_KEYPAD_MULTIPLY code*/
+ APP_USBD_HID_KBD_KEYPAD_MINUS = 86, /**<KBD_KEYPAD_MINUS code*/
+ APP_USBD_HID_KBD_KEYPAD_PLUS = 87, /**<KBD_KEYPAD_PLUS code*/
+ APP_USBD_HID_KBD_KEYPAD_ENTER = 88, /**<KBD_KEYPAD_ENTER code*/
+ APP_USBD_HID_KBD_KEYPAD_1 = 89, /**<KBD_KEYPAD_1 code*/
+ APP_USBD_HID_KBD_KEYPAD_2 = 90, /**<KBD_KEYPAD_2 code*/
+ APP_USBD_HID_KBD_KEYPAD_3 = 91, /**<KBD_KEYPAD_3 code*/
+ APP_USBD_HID_KBD_KEYPAD_4 = 92, /**<KBD_KEYPAD_4 code*/
+ APP_USBD_HID_KBD_KEYPAD_5 = 93, /**<KBD_KEYPAD_5 code*/
+ APP_USBD_HID_KBD_KEYPAD_6 = 94, /**<KBD_KEYPAD_6 code*/
+ APP_USBD_HID_KBD_KEYPAD_7 = 95, /**<KBD_KEYPAD_7 code*/
+ APP_USBD_HID_KBD_KEYPAD_8 = 96, /**<KBD_KEYPAD_8 code*/
+ APP_USBD_HID_KBD_KEYPAD_9 = 97, /**<KBD_KEYPAD_9 code*/
+ APP_USBD_HID_KBD_KEYPAD_0 = 98, /**<KBD_KEYPAD_0 code*/
+} app_usbd_hid_kbd_codes_t;
+
+/**
+ * @brief HID keyboard modifier
+ */
+typedef enum {
+ APP_USBD_HID_KBD_MODIFIER_NONE = 0x00, /**< MODIFIER_NONE bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_CTRL = 0x01, /**< MODIFIER_LEFT_CTRL bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_SHIFT = 0x02, /**< MODIFIER_LEFT_SHIFT bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_ALT = 0x04, /**< MODIFIER_LEFT_ALT bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_UI = 0x08, /**< MODIFIER_LEFT_UI bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_CTRL = 0x10, /**< MODIFIER_RIGHT_CTRL bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_SHIFT = 0x20, /**< MODIFIER_RIGHT_SHIFT bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_ALT = 0x40, /**< MODIFIER_RIGHT_ALT bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_UI = 0x80, /**< MODIFIER_RIGHT_UI bit*/
+} app_usbd_hid_kbd_modifier_t;
+
+/**
+ * @brief HID keyboard LEDs.
+ */
+typedef enum {
+ APP_USBD_HID_KBD_LED_NUM_LOCK = 0x01, /**< LED_NUM_LOCK id*/
+ APP_USBD_HID_KBD_LED_CAPS_LOCK = 0x02, /**< LED_CAPS_LOCK id*/
+ APP_USBD_HID_KBD_LED_SCROLL_LOCK = 0x04, /**< LED_SCROLL_LOCK id*/
+ APP_USBD_HID_KBD_LED_COMPOSE = 0x08, /**< LED_COMPOSE id*/
+ APP_USBD_HID_KBD_LED_KANA = 0x10, /**< LED_KANA id*/
+} app_usbd_hid_kbd_led_t;
+
+
+
+#ifdef DOXYGEN
+/**
+ * @brief HID keyboard class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_hid_kbd_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_hid_kbd, \
+ APP_USBD_HID_KBD_CONFIG(0, NRF_DRV_USBD_EPIN1), \
+ APP_USBD_HID_KBD_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_HID_KBD_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+/**
+ * @brief Global definition of app_usbd_hid_kbd_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param interface_number Unique interface index.
+ * @param endpoint Input endpoint (@ref nrf_drv_usbd_ep_t).
+ * @param user_ev_handler User event handler (optional parameter: NULL might be passed here).
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ *
+ * Example class definition:
+ * @code
+ APP_USBD_HID_KBD_GLOBAL_DEF(my_awesome_kbd, 0, NRF_DRV_USBD_EPIN1, NULL, APP_USBD_HID_SUBCLASS_BOOT);
+ * @endcode
+ */
+#define APP_USBD_HID_KBD_GLOBAL_DEF(instance_name, interface_number, endpoint, user_ev_handler, subclass_boot) \
+ APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(keyboard_desc, APP_USBD_HID_KBD_REPORT_DSC()); \
+ static const app_usbd_hid_subclass_desc_t * keyboard_descs[] = {&keyboard_desc}; \
+ APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ user_ev_handler, \
+ subclass_boot)
+
+/**
+ * @brief Helper function to get class instance from HID keyboard internals.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_hid_kbd_class_inst_get(app_usbd_hid_kbd_t const * p_kbd)
+{
+ return &p_kbd->base;
+}
+
+/**
+ * @brief Helper function to get HID keyboard from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return HID keyboard class handle.
+ */
+static inline app_usbd_hid_kbd_t const *
+app_usbd_hid_kbd_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_hid_kbd_t const *)p_inst;
+}
+
+/**
+ * @brief Set HID keyboard modifier state.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ * @param[in] modifier Type of modifier.
+ * @param[in] state State, true active, false inactive.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_modifier_t modifier,
+ bool state);
+
+
+/**
+ * @brief Press/release HID keyboard key.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ * @param[in] key Keyboard key code.
+ * @param[in] press True -> key press, false -> release.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_codes_t key,
+ bool press);
+/**
+ * @brief HID Keyboard LEDs state get.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ * @param[in] led LED code.
+ *
+ * @retval true LED is set.
+ * @retval false LED is not set.
+ */
+bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_led_t led);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_KBD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h
new file mode 100644
index 0000000..1083b42
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_KBD_DESC_H__
+#define APP_USBD_HID_KBD_DESC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_hid_kbd_desc USB HID keyboard descriptors
+ * @ingroup app_usbd_hid_kbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for HID keyboard class.
+ *
+ * @param interface_number Interface number.
+ */
+#define APP_USBD_HID_KBD_INTERFACE_DSC(interface_number) \
+ APP_USBD_HID_INTERFACE_DSC(interface_number, \
+ 1, \
+ APP_USBD_HID_SUBCLASS_BOOT, \
+ APP_USBD_HID_PROTO_KEYBOARD)
+
+/**
+ * @brief Initializer of HID descriptor for HID keyboard class.
+ *
+ * @param ... Report descriptor item.
+ */
+#define APP_USBD_HID_KBD_HID_DSC(...) \
+ APP_USBD_HID_HID_DSC(__VA_ARGS__)
+/**
+ * @brief Initializer of endpoint descriptor for HID keyboard class.
+ *
+ * @param endpoint Endpoint number.
+ */
+#define APP_USBD_HID_KBD_EP_DSC(endpoint) \
+ APP_USBD_HID_EP_DSC(endpoint, 8, 1)
+
+
+/**
+ * @brief Example of USB HID keyboard report descriptor.
+ *
+ */
+#define APP_USBD_HID_KBD_REPORT_DSC() { \
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\
+ 0x09, 0x06, /* USAGE (Keyboard) */\
+ 0xa1, 0x01, /* COLLECTION (Application) */\
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\
+ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */\
+ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */\
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */\
+ 0x75, 0x01, /* REPORT_SIZE (1) */\
+ 0x95, 0x08, /* REPORT_COUNT (8) */\
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */\
+ 0x95, 0x01, /* REPORT_COUNT (1) */\
+ 0x75, 0x08, /* REPORT_SIZE (8) */\
+ 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */\
+ 0x95, 0x05, /* REPORT_COUNT (5) */\
+ 0x75, 0x01, /* REPORT_SIZE (1) */\
+ 0x05, 0x08, /* USAGE_PAGE (LEDs) */\
+ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */\
+ 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */\
+ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */\
+ 0x95, 0x01, /* REPORT_COUNT (1) */\
+ 0x75, 0x03, /* REPORT_SIZE (3) */\
+ 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */\
+ 0x95, 0x06, /* REPORT_COUNT (6) */\
+ 0x75, 0x08, /* REPORT_SIZE (8) */\
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
+ 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */\
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\
+ 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated))*/\
+ 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */\
+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */\
+ 0xc0 /* END_COLLECTION */\
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_KBD_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h
new file mode 100644
index 0000000..06ab405
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h
@@ -0,0 +1,174 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_KBD_INTERNAL_H__
+#define APP_USBD_HID_KBD_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_hid_kbd_internal USB HID keyboard internals
+ * @ingroup app_usbd_hid_kbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of HID keyboard class type.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_hid_kbd);
+
+
+/**
+ * @brief HID keyboard part of class instance data.
+ *
+ */
+typedef struct {
+ app_usbd_hid_inst_t hid_inst; //!< HID instance data.
+} app_usbd_hid_kbd_inst_t;
+
+/**
+ * @brief HID keyboard context
+ *
+ */
+typedef struct {
+ app_usbd_hid_ctx_t hid_ctx; //!< HID class context.
+
+ struct app_usbd_hid_kbd_ctx_internal_s {
+ uint8_t modifier; //!< Keyboard modifier state @ref app_usbd_hid_kbd_modifier_t.
+ uint8_t reserved; //!< Reserved value.
+ uint8_t key_table[6]; //!< Keyboard keys table @ref app_usbd_hid_kbd_codes_t.
+ } rep;
+
+ uint8_t report_buff[8]; //!< Raw report buffer.
+ uint8_t leds_state; //!< Output report LEDs state.
+ uint8_t set_report; //!< Set report flag.
+} app_usbd_hid_kbd_ctx_t;
+
+/**
+ * @brief HID keyboard configuration macro.
+ *
+ * Used by @ref APP_USBD_HID_KBD_GLOBAL_DEF.
+ *
+ *
+ */
+#define APP_USBD_HID_KBD_CONFIG(iface, ep) ((iface, ep))
+
+
+/**
+ * @brief Specific class constant data for HID keyboard class.
+ */
+#define APP_USBD_HID_KBD_INSTANCE_SPECIFIC_DEC app_usbd_hid_kbd_inst_t inst;
+
+/**
+ * @brief Specific class data for HID keyboard class.
+ */
+#define APP_USBD_HID_KBD_DATA_SPECIFIC_DEC app_usbd_hid_kbd_ctx_t ctx;
+
+
+/**
+ * @brief Configure internal part of HID keyboard instance.
+ *
+ * @param report_buff_in Input report buffers array.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler User event handler.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ */
+#define APP_USBD_HID_KBD_INST_CONFIG(report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ subclass_boot) \
+ .inst = { \
+ .hid_inst = APP_USBD_HID_INST_CONFIG(keyboard_descs, \
+ subclass_boot, \
+ APP_USBD_HID_PROTO_KEYBOARD, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ &app_usbd_hid_kbd_methods), \
+}
+
+
+/**
+ * @brief Public HID keyboard interface.
+ */
+extern const app_usbd_hid_methods_t app_usbd_hid_kbd_methods;
+
+/**
+ * @brief Public HID keyboard class interface.
+ */
+extern const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_hid_kbd_t class.
+ *
+ * @ref APP_USBD_HID_KBD_GLOBAL_DEF
+ */
+#define APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ user_ev_handler, \
+ subclass_boot) \
+ static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \
+ APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), 1 + 1); \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_hid_kbd, \
+ &app_usbd_hid_kbd_class_methods, \
+ APP_USBD_HID_KBD_CONFIG(interface_number, endpoint), \
+ (APP_USBD_HID_KBD_INST_CONFIG(CONCAT_2(instance_name, _in), \
+ &CONCAT_2(instance_name, _out), \
+ user_ev_handler, \
+ subclass_boot)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_KBD_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c
new file mode 100644
index 0000000..7427c58
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c
@@ -0,0 +1,620 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID_MOUSE)
+
+#include <string.h>
+#include "app_usbd_hid_mouse.h"
+#include "app_util_platform.h"
+
+
+/**
+ * @defgroup app_usbd_hid_mouse_internal USBD HID Mouse internals
+ * @{
+ * @ingroup app_usbd_hid_mouse
+ * @internal
+ */
+
+/**
+ * @brief Auxiliary function to access HID mouse context data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID mouse instance data context.
+ */
+static inline app_usbd_hid_mouse_ctx_t * hid_mouse_ctx_get(app_usbd_hid_mouse_t const * p_mouse)
+{
+ ASSERT(p_mouse != NULL);
+ ASSERT(p_mouse->specific.p_data != NULL);
+ return &p_mouse->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access HID mouse instance data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID mouse instance.
+ */
+static inline app_usbd_hid_mouse_t const * hid_mouse_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_hid_mouse_t const *)p_inst;
+}
+
+
+/**
+ * @brief Returns mouse report buffer handle.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @return HID report buffer.
+ */
+static inline
+app_usbd_hid_report_buffer_t const * hid_mouse_rep_buffer_get(app_usbd_hid_mouse_t const * p_mouse)
+{
+ ASSERT(p_mouse != NULL);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+ app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst);
+
+ p_rep_buff->p_buff = p_mouse_ctx->report_buff;
+ p_rep_buff->size = sizeof(p_mouse_ctx->report_buff);
+
+ /*Mouse has only one report input report buffer */
+ return app_usbd_hid_rep_buff_in_get(p_hinst);
+}
+
+
+/**@brief Auxiliary function to get report value from internal accumulated value.
+ *
+ * @param[in] acc Accumulated XY axis or scroll.
+ *
+ * @return Offset value that could be written directly to report buffer.
+ */
+static inline int8_t hid_mouse_axis_acc_get(int16_t acc)
+{
+ if (acc > INT8_MAX)
+ {
+ return INT8_MAX;
+ }
+
+ if (acc < INT8_MIN)
+ {
+ return INT8_MIN;
+ }
+
+ return acc;
+}
+
+
+/**@brief Auxiliary function to prepare report transfer buffer to next transfer.
+ *
+ * @param[in] p_mouse_ctx Mouse internal context.
+ *
+ * @retval true Next transfer is required.
+ * @retval false Next transfer is not required.
+ */
+static inline bool hid_mouse_transfer_next(app_usbd_hid_mouse_t const * p_mouse)
+{
+
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse);
+
+ uint8_t * p_buff = p_rep_buffer->p_buff;
+
+ /*Save last buttons state*/
+ uint8_t last_button_state = p_buff[0];
+
+ /*Button state*/
+ p_buff[0] = p_mouse_ctx->button_state;
+
+ /*Axis X*/
+ int8_t val_x = hid_mouse_axis_acc_get(p_mouse_ctx->acc_x_axis);
+ p_mouse_ctx->acc_x_axis -= val_x;
+ p_buff[1] = val_x;
+
+ /*Axis Y*/
+ int8_t val_y = hid_mouse_axis_acc_get(p_mouse_ctx->acc_y_axis);
+ p_mouse_ctx->acc_y_axis -= val_y;
+ p_buff[2] = val_y;
+
+ /*Scroll*/
+ int8_t val_scroll = hid_mouse_axis_acc_get(p_mouse_ctx->acc_scroll);
+ p_mouse_ctx->acc_scroll -= val_scroll;
+ p_buff[3] = val_scroll;
+
+ if (val_x || val_y || val_scroll)
+ {
+ /*New transfer is required if any of mouse relative position is not zero*/
+ return true;
+ }
+
+ if (last_button_state != p_buff[0])
+ {
+ /*New transfer is required if button state has changed*/
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * @brief Triggers IN endpoint transfer.
+ *
+ * @param[in] p_mouse HID mouse instance.
+ *
+ * @return Standard error code.
+ */
+static inline ret_code_t hid_mouse_transfer_set(app_usbd_hid_mouse_t const * p_mouse)
+{
+ app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_mouse;
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst);
+
+ app_usbd_hid_state_flag_clr(&p_mouse_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ if (!hid_mouse_transfer_next(p_mouse))
+ {
+ /* Transfer buffer hasn't changed since last transfer. No need to setup
+ * next transfer.
+ * */
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse);
+
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(ep_addr, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_hid_state_flag_set(&p_mouse_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief Checks if adding would cause 16 bit signed integer overflow.
+ *
+ * @param[in] acc Signed 16 bit accumulator to test.
+ * @param[in] value Value to add to accumulator.
+ *
+ * @retval true Overflow detected.
+ * @retval false No overflow detected.
+ */
+static inline bool hid_mouse_acc_overflow_check(int16_t acc, int8_t val)
+{
+ if (((int32_t)acc + val) > INT16_MAX)
+ {
+ return true;
+ }
+
+ if (((int32_t)acc + val) < INT16_MIN)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset)
+{
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (offset == 0)
+ {
+ /*No position change*/
+ return NRF_SUCCESS;
+ }
+
+ if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset))
+ {
+ /*Overflow detected*/
+ return NRF_ERROR_BUSY;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ p_mouse_ctx->acc_x_axis += offset;
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset)
+{
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (offset == 0)
+ {
+ /*No position change*/
+ return NRF_SUCCESS;
+ }
+
+ if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset))
+ {
+ /*Overflow detected*/
+ return NRF_ERROR_BUSY;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ p_mouse_ctx->acc_y_axis += offset;
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset)
+{
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (offset == 0)
+ {
+ /*No position change*/
+ return NRF_SUCCESS;
+ }
+
+ if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_scroll, offset))
+ {
+ /*Overflow detected*/
+ return NRF_ERROR_BUSY;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ p_mouse_ctx->acc_scroll += offset;
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse,
+ uint8_t button_id,
+ bool state)
+{
+ ASSERT(button_id < 8);
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (button_id >= p_mouse->specific.inst.button_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (IS_SET(p_mouse_ctx->button_state, button_id) == (state ? 1 : 0))
+ {
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ if (state)
+ {
+ SET_BIT(p_mouse_ctx->button_state, button_id);
+ }
+ else
+ {
+ CLR_BIT(p_mouse_ctx->button_state, button_id);
+ }
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_get_report
+ */
+static ret_code_t hid_mouse_on_get_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_INPUT)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse);
+
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size);
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_set_report
+ */
+static ret_code_t hid_mouse_on_set_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::ep_transfer_set
+ */
+static ret_code_t hid_mouse_ep_transfer_in(app_usbd_class_inst_t const * p_inst)
+{
+ return hid_mouse_transfer_set((app_usbd_hid_mouse_t const *)p_inst);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::event_handler
+ */
+static ret_code_t hid_mouse_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+ app_usbd_hid_ctx_t * p_hid_ctx = &p_mouse_ctx->hid_ctx;
+
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_event->app_evt.type)
+ {
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (ret != NRF_ERROR_NOT_SUPPORTED)
+ {
+ /* Event was processed by specific handler */
+ return ret;
+ }
+
+ /*Try handle event by generic HID event handler*/
+ return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+}
+
+
+static uint8_t hid_mouse_get_class_descriptors_count(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->subclass_desc_count;
+}
+
+
+static app_usbd_descriptor_t hid_mouse_get_class_descriptors_type(
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->type;
+}
+
+
+static size_t hid_mouse_get_class_descriptors_length(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->size;
+}
+
+
+static uint8_t hid_mouse_get_class_descriptors_data(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num,
+ uint32_t cur_byte)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->p_data[cur_byte];
+}
+
+
+static bool hid_mouse_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_CLASS); // bInterfaceClass = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_mouse->specific.inst.hid_inst.subclass_boot); // bInterfaceSubclass (Boot Interface)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_mouse->specific.inst.hid_inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HID DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_DESCRIPTOR_HID); // bDescriptorType = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(APP_USBD_HID_BCD_VER)); // bcdHID LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(APP_USBD_HID_BCD_VER)); // bcdHID MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_COUNTRY_NOT_SUPPORTED); // bCountryCode
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_mouse_get_class_descriptors_count(p_inst)); // bNumDescriptors
+
+ static uint8_t class_desc_cnt = 0;
+ class_desc_cnt = hid_mouse_get_class_descriptors_count(p_inst);
+ static uint8_t j = 0;
+ static uint16_t class_desc_len = 0;
+
+ for (j = 0; j < class_desc_cnt; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_mouse_get_class_descriptors_type(p_inst, j)); // bDescriptorType
+
+ class_desc_len = hid_mouse_get_class_descriptors_length(p_inst, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(class_desc_len)); // wDescriptorLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(class_desc_len)); // wDescriptorLength MSB
+ }
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ for (j = 0; j < endpoints; j++)
+ {
+ /* ENDPOINT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLengths
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ }
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+static bool hid_mouse_feed_subclass_descriptor(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size,
+ uint8_t index)
+{
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* PHYSICAL AND REPORT DESCRIPTORS */
+ static uint32_t cur_byte = 0;
+ static size_t sub_desc_size = 0;
+ sub_desc_size = hid_mouse_get_class_descriptors_length(p_inst, index);
+
+ for (cur_byte = 0; cur_byte <= sub_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_mouse_get_class_descriptors_data(p_inst, index, cur_byte));
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/** @} */
+
+const app_usbd_hid_methods_t app_usbd_hid_mouse_methods = {
+ .on_get_report = hid_mouse_on_get_report,
+ .on_set_report = hid_mouse_on_set_report,
+ .ep_transfer_in = hid_mouse_ep_transfer_in,
+ .ep_transfer_out = NULL,
+ .feed_subclass_descriptor = hid_mouse_feed_subclass_descriptor,
+};
+
+const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods = {
+ .event_handler = hid_mouse_event_handler,
+ .feed_descriptors = hid_mouse_feed_descriptors,
+};
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID_MOUSE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h
new file mode 100644
index 0000000..2293f3c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_MOUSE_H__
+#define APP_USBD_HID_MOUSE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd_hid.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+#include "app_usbd_hid_mouse_desc.h"
+#include "app_usbd_hid_mouse_internal.h"
+
+/**
+ * @defgroup app_usbd_hid_mouse USB HID mouse
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class.
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief HID mouse class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_hid_mouse_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_hid_mouse, \
+ APP_USBD_HID_MOUSE_CONFIG(0, NRF_DRV_USBD_EPIN1), \
+ APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+/**
+ * @brief Global definition macro of app_usbd_hid_mouse_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param interface_number Unique interface number.
+ * @param endpoint Input endpoint (@ref nrf_drv_usbd_ep_t).
+ * @param bcnt Mouse button count (from 1 to 8).
+ * @param user_ev_handler User event handler (optional).
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL.
+ *
+ * @code
+ APP_USBD_HID_MOUSE_GLOBAL_DEF(my_awesome_mouse, 0, NRF_DRV_USBD_EPIN1, 3, NULL);
+ * @endcode
+ */
+#define APP_USBD_HID_MOUSE_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ endpoint, \
+ bcnt, \
+ user_ev_handler, \
+ subclass_boot) \
+ APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(mouse_desc, APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt)); \
+ static const app_usbd_hid_subclass_desc_t * mouse_descs[] = {&mouse_desc}; \
+ APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ bcnt, \
+ user_ev_handler, \
+ subclass_boot)
+
+
+/**
+ * @brief Helper function to get class instance from HID mouse internals.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_hid_mouse_class_inst_get(app_usbd_hid_mouse_t const * p_mouse)
+{
+ return &p_mouse->base;
+}
+
+/**
+ * @brief Helper function to get HID mouse from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return HID mouse class handle.
+ */
+static inline app_usbd_hid_mouse_t const *
+app_usbd_hid_mouse_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_hid_mouse_t const *)p_inst;
+}
+
+/**
+ * @brief Move mouse X axis.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] offset Relative mouse position: allowed full int8_t range.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset);
+
+/**
+ * @brief Move mouse Y axis.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] offset Relative mouse position: allowed full int8_t range.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset);
+
+/**
+ * @brief Move mouse scroll.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] offset Relative mouse position: allowed full int8_t range.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset);
+
+/**
+ * @brief Set mouse button state.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] button_id Button number (0...7).
+ * @param[in] state Button state: true -> PRESSED, false -> RELEASED.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse,
+ uint8_t button_id,
+ bool state);
+
+/** @} */
+
+#endif /* APP_USBD_HID_MOUSE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h
new file mode 100644
index 0000000..e7517c2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_MOUSE_DESC_H__
+#define APP_USBD_HID_MOUSE_DESC_H__
+
+/**
+ * @defgroup app_usbd_hid_mouse_desc USB HID mouse descriptors
+ * @ingroup app_usbd_hid_mouse
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for HID mouse class.
+ *
+ * @param interface_number Interface number.
+ */
+#define APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \
+ APP_USBD_HID_INTERFACE_DSC(interface_number, \
+ 1, \
+ APP_USBD_HID_SUBCLASS_BOOT, \
+ APP_USBD_HID_PROTO_MOUSE)
+
+/**
+ * @brief Initializer of HID descriptor for HID mouse class.
+ *
+ * @param ... Descriptor list.
+ */
+#define APP_USBD_HID_MOUSE_HID_DSC(...) \
+ APP_USBD_HID_HID_DSC(__VA_ARGS__)
+
+/**
+ * @brief Initializer of endpoint descriptor for HID mouse class.
+ *
+ * @param endpoint_number Endpoint number.
+ */
+#define APP_USBD_HID_MOUSE_EP_DSC(endpoint_number) \
+ APP_USBD_HID_EP_DSC(endpoint_number, 8, 1)
+
+
+
+/**
+ * @brief Example of USB HID mouse report descriptor for n button mouse.
+ *
+ * @param bcnt Button count. Allowed values from 1 to 8.
+ */
+#define APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt) { \
+ 0x05, 0x01, /* Usage Page (Generic Desktop), */ \
+ 0x09, 0x02, /* Usage (Mouse), */ \
+ 0xA1, 0x01, /* Collection (Application), */ \
+ 0x09, 0x01, /* Usage (Pointer), */ \
+ 0xA1, 0x00, /* Collection (Physical), */ \
+ 0x05, 0x09, /* Usage Page (Buttons), */ \
+ 0x19, 0x01, /* Usage Minimum (01), */ \
+ 0x29, bcnt, /* Usage Maximum (bcnt), */ \
+ 0x15, 0x00, /* Logical Minimum (0), */ \
+ 0x25, 0x01, /* Logical Maximum (1), */ \
+ 0x75, 0x01, /* Report Size (1), */ \
+ 0x95, bcnt, /* Report Count (bcnt), */ \
+ 0x81, 0x02, /* Input (Data, Variable, Absolute)*/ \
+ 0x75, (8-(bcnt)), /* Report Size (8-(bcnt)), */ \
+ 0x95, 0x01, /* Report Count (1), */ \
+ 0x81, 0x01, /* Input (Constant), */ \
+ 0x05, 0x01, /* Usage Page (Generic Desktop), */ \
+ 0x09, 0x30, /* Usage (X), */ \
+ 0x09, 0x31, /* Usage (Y), */ \
+ 0x09, 0x38, /* Usage (Scroll), */ \
+ 0x15, 0x81, /* Logical Minimum (-127), */ \
+ 0x25, 0x7F, /* Logical Maximum (127), */ \
+ 0x75, 0x08, /* Report Size (8), */ \
+ 0x95, 0x03, /* Report Count (3), */ \
+ 0x81, 0x06, /* Input (Data, Variable, Relative)*/ \
+ 0xC0, /* End Collection, */ \
+ 0xC0, /* End Collection */ \
+}
+
+ /** @} */
+
+#endif /* APP_USBD_HID_MOUSE_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h
new file mode 100644
index 0000000..64ccc7f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_HID_MOUSE_INTERNAL_H__
+#define APP_USBD_HID_MOUSE_INTERNAL_H__
+
+/**
+ * @defgroup app_usbd_hid_mouse_internals USB HID mouse internals
+ * @ingroup app_usbd_hid_mouse
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of HID mouse class type.
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_hid_mouse);
+
+
+/**
+ * @brief HID mouse part of class instance data.
+ */
+typedef struct {
+ app_usbd_hid_inst_t hid_inst; //!< HID instance data.
+ const uint8_t button_count; //!< Number of buttons mouse specific.
+} app_usbd_hid_mouse_inst_t;
+
+/**
+ * @brief HID mouse context.
+ */
+typedef struct {
+ app_usbd_hid_ctx_t hid_ctx; //!< HID class context.
+
+ int16_t acc_x_axis; //!< Mouse specific. Accumulated x axis offset.
+ int16_t acc_y_axis; //!< Mouse specific. Accumulated y axis offset.
+ int16_t acc_scroll; //!< Mouse specific. Accumulated scroll offset.
+ uint8_t button_state; //!< Mouse specific. Actual button state. Bitfield of maximum 8 buttons states.
+ uint8_t report_buff[4];
+} app_usbd_hid_mouse_ctx_t;
+
+
+/**
+ * @brief HID mouse configuration macro.
+ *
+ * Used by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF.
+ *
+ */
+#define APP_USBD_HID_MOUSE_CONFIG(iface, ep) ((iface, ep))
+
+
+/**
+ * @brief Specific class constant data for HID mouse class.
+ */
+#define APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC app_usbd_hid_mouse_inst_t inst;
+
+/**
+ * @brief Specific class data for HID mouse class.
+ */
+#define APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC app_usbd_hid_mouse_ctx_t ctx;
+
+
+/**
+ * @brief HID mouse descriptors config macro
+ *
+ * @ref app_usbd_hid_mouse_inst_t
+ *
+ */
+#define APP_USBD_HID_MOUSE_DSC_CONFIG(interface_number, endpoint, rep_desc) { \
+ APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \
+ APP_USBD_HID_MOUSE_HID_DSC(rep_desc) \
+ APP_USBD_HID_MOUSE_EP_DSC(endpoint) \
+}
+
+/**
+ * @brief Configure internal part of HID mouse instance.
+ *
+ * @param report_buff_in Input report buffers array.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler User event handler.
+ * @param bcnt Mouse button count.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ */
+#define APP_USBD_HID_MOUSE_INST_CONFIG(report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ bcnt, \
+ subclass_boot) \
+ .inst = { \
+ .hid_inst = APP_USBD_HID_INST_CONFIG(mouse_descs, \
+ subclass_boot, \
+ APP_USBD_HID_PROTO_MOUSE, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ &app_usbd_hid_mouse_methods), \
+ .button_count = bcnt, \
+ }
+
+/**
+ * @brief Public HID mouse interface.
+ */
+extern const app_usbd_hid_methods_t app_usbd_hid_mouse_methods;
+
+/**
+ * @brief Public HID mouse class interface.
+ */
+extern const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods;
+
+/**
+ * @brief Global definition of app_usbd_hid_mouse_t class.
+ *
+ * @ref APP_USBD_HID_MOUSE_GLOBAL_DEF
+ */
+#define APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ bcnt, \
+ user_ev_handler, \
+ subclass_boot) \
+ static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_hid_mouse, \
+ &app_usbd_hid_mouse_class_methods, \
+ APP_USBD_HID_MOUSE_CONFIG(interface_number, endpoint), \
+ (APP_USBD_HID_MOUSE_INST_CONFIG(CONCAT_2(instance_name, _in), \
+ NULL, \
+ user_ev_handler, \
+ bcnt, \
+ subclass_boot)) \
+ )
+
+
+/** @} */
+
+#endif /* APP_USBD_HID_MOUSE_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c
new file mode 100644
index 0000000..a19de11
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c
@@ -0,0 +1,2365 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_MSC)
+
+#include <string.h>
+#include <ctype.h>
+#include "app_usbd.h"
+#include "app_usbd_msc.h"
+#include "app_usbd_string_desc.h"
+
+/**
+ * @defgroup app_usbd_msc_internal USBD MSC internals
+ * @{
+ * @ingroup app_usbd_msc
+ * @internal
+ */
+
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_resp_t) == 18);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_resp_t) == 36);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read6_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write6_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_resp_t) == 4);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_resp_t) == 8);
+
+STATIC_ASSERT(sizeof(app_usbd_msc_cbw_t) == 31);
+STATIC_ASSERT(sizeof(app_usbd_msc_csw_t) == 13);
+
+#define NRF_LOG_MODULE_NAME usbd_msc
+
+#if APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_MSC_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_MSC_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_MSC_CONFIG_DEBUG_COLOR
+#else // APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // APP_USBD_MSC_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define APP_USBD_MSC_IFACE_IDX 0 /**< Mass storage class interface index */
+#define APP_USBD_MSC_EPIN_IDX 0 /**< Mass storage class endpoint IN index */
+#define APP_USBD_MSC_EPOUT_IDX 1 /**< Mass storage class endpoint OUT index */
+
+/**
+ * @brief Set request buffer busy flag
+ *
+ * @param[in] val Bitmask to set
+ * @param[in] id Buffer id
+ * */
+#define APP_USBD_MSC_REQ_BUSY_SET(val, id) SET_BIT(val, id)
+
+/**
+ * @brief Clear request buffer busy flag
+ *
+ * @param[in] val Bitmask to set
+ * @param[in] id Buffer id
+ * */
+#define APP_USBD_MSC_REQ_BUSY_CLR(val, id) CLR_BIT(val, id)
+
+#define APP_USBD_MSC_REQ_BUSY_FULL_MASK (0x03) /**< Request busy mask */
+
+static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event);
+
+/**
+ * @brief Auxiliary function to access MSC instance data
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return MSC instance data @ref app_usbd_msc_t
+ */
+static inline app_usbd_msc_t const * msc_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_msc_t const *)p_inst;
+}
+
+
+/**
+ * @brief Auxiliary function to access MSC context data
+ *
+ * @param[in] p_msc MSC instance data
+ * @return MSC context data @ref app_usbd_msc_ctx_t
+ */
+static inline app_usbd_msc_ctx_t * msc_ctx_get(app_usbd_msc_t const * p_msc)
+{
+ ASSERT(p_msc != NULL);
+ ASSERT(p_msc->specific.p_data != NULL);
+ return &p_msc->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access MSC IN endpoint address
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return IN endpoint address
+ */
+static inline nrf_drv_usbd_ep_t ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+
+/**
+ * @brief Auxiliary function to access MSC OUT endpoint address
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return OUT endpoint address
+ */
+static inline nrf_drv_usbd_ep_t ep_out_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+
+/**
+ * @brief Command Block Wrapper trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t cbw_wait_start(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst);
+
+ NRF_LOG_DEBUG("cbw_wait_start");
+ memset(&p_msc_ctx->cbw, 0, sizeof(app_usbd_msc_cbw_t));
+ NRF_DRV_USBD_TRANSFER_OUT(cbw, &p_msc_ctx->cbw, sizeof(app_usbd_msc_cbw_t));
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_out, &cbw);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = APP_USBD_MSC_STATE_CBW;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Command Status Wrapper trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t csw_wait_start(app_usbd_class_inst_t const * p_inst, uint8_t status)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst);
+
+ memset(&p_msc_ctx->csw, 0, sizeof(app_usbd_msc_csw_t));
+ memcpy(p_msc_ctx->csw.signature, APP_USBD_MSC_CSW_SIGNATURE, sizeof(p_msc_ctx->csw.signature));
+ memcpy(p_msc_ctx->csw.tag, p_msc_ctx->cbw.tag, sizeof(p_msc_ctx->csw.tag));
+ memcpy(p_msc_ctx->csw.residue, &p_msc_ctx->current.residue, sizeof(uint32_t));
+ p_msc_ctx->csw.status = status;
+
+ NRF_DRV_USBD_TRANSFER_IN(csw, &p_msc_ctx->csw, sizeof(app_usbd_msc_csw_t));
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_in, &csw);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = APP_USBD_MSC_STATE_CSW;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief IN transfer trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_buff IN transfer data buffer
+ * @param[in] size IN transfer size
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t transfer_in_start(app_usbd_class_inst_t const * p_inst,
+ void const * p_buff,
+ size_t size,
+ app_usbd_msc_state_t state)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("transfer_in_start: p_buff: %p, size: %u", (uint32_t)p_buff, size);
+
+ nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_IN(resp, p_buff, size);
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_in, &resp);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = state;
+ }
+ return ret;
+}
+
+
+/**
+ * @brief MSC reset request handler @ref APP_USBD_MSC_REQ_BULK_RESET
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * */
+static void bulk_ep_reset(app_usbd_class_inst_t const * p_inst)
+{
+ nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_ep_abort(ep_addr_in);
+ nrf_drv_usbd_ep_abort(ep_addr_out);
+}
+
+
+/**
+ * @brief OUT transfer trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_buff OUT transfer data buffer
+ * @param[in] size OUT transfer size
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t transfer_out_start(app_usbd_class_inst_t const * p_inst,
+ void * p_buff,
+ size_t size,
+ app_usbd_msc_state_t state)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("transfer_out_start: p_buff: %p, size: %u", (uint32_t)p_buff, size);
+ nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_OUT(resp, p_buff, size);
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_out, &resp);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = state;
+ }
+ return ret;
+}
+
+
+/**
+ * @brief Generic function to stall communication endpoints and mark error state
+ *
+ * Function used internally to stall all communication endpoints and mark current state.
+ *
+ * @param p_inst Generic class instance
+ * @param state State to set
+ */
+static void status_generic_error_stall(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_state_t state)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ nrf_drv_usbd_ep_t ep_in = ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_t ep_out = ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_ep_stall(ep_in);
+ nrf_drv_usbd_ep_stall(ep_out);
+ nrf_drv_usbd_ep_abort(ep_in);
+ nrf_drv_usbd_ep_abort(ep_out);
+
+ p_msc_ctx->state = state;
+}
+
+
+/**
+ * @brief Start status stage of unsupported SCSI command
+ *
+ * @param[in,out] p_inst Generic class instance
+ *
+ * @return Standard error code
+ *
+ * @sa status_generic_error_stall
+ */
+static ret_code_t status_unsupported_start(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+ bool data_stage = uint32_decode(p_msc_ctx->cbw.datlen) != 0;
+
+ if (!data_stage)
+ {
+ /* Try to transfer the response now */
+ ret_code_t ret;
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ if (ret == NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ /* Cannot transfer failed response in current command - stall the endpoints and postpone the answer */
+ status_generic_error_stall(p_inst, APP_USBD_MSC_STATE_UNSUPPORTED);
+ if (data_stage)
+ {
+ if (!(p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN))
+ {
+ nrf_drv_usbd_transfer_out_drop(ep_out_addr_get(p_inst));
+ }
+ /* Unsupported command so we did not process any data - mark it in current residue value */
+ p_msc_ctx->current.residue = uint32_decode(p_msc_ctx->cbw.datlen);
+ }
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Start status stage of CBW invalid
+ *
+ * @param[in,out] p_inst Generic class instance
+ *
+ * @sa status_generic_error_stall
+ */
+static void status_cbwinvalid_start(app_usbd_class_inst_t const * p_inst)
+{
+ status_generic_error_stall(p_inst, APP_USBD_MSC_STATE_CBW_INVALID);
+}
+
+
+/**
+ * @brief Start status stage of internal device error
+ *
+ * Kind of error that requires bulk reset but does not stall endpoint permanently - the correct
+ * answer is possible.
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @sa status_generic_error_stall
+ */
+static void status_deverror_start(app_usbd_class_inst_t const * p_inst)
+{
+ status_generic_error_stall(p_inst, APP_USBD_MSC_STATE_DEVICE_ERROR);
+}
+
+
+/**
+ * @brief Internal SETUP standard IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by MSC class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ * @retval NRF_ERROR_FORBIDDEN if endpoint stall cannot be cleared because of internal state
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ app_usbd_setup_reqrec_t req_rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType);
+
+ if ((req_rec == APP_USBD_SETUP_REQREC_ENDPOINT) &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_CLEAR_FEATURE) &&
+ (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT))
+ {
+ if (p_msc_ctx->state == APP_USBD_MSC_STATE_CBW_INVALID)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ ret_code_t ret = NRF_SUCCESS;
+ /* Clearing endpoint here. It is done normally inside app_usbd, but we are overwritting this functionality */
+ nrf_drv_usbd_ep_t ep_addr = (nrf_drv_usbd_ep_t)(p_setup_ev->setup.wIndex.lb);
+ nrf_drv_usbd_ep_dtoggle_clear(ep_addr);
+ nrf_drv_usbd_ep_stall_clear(ep_addr);
+ if (NRF_USBD_EPIN_CHECK(ep_addr))
+ {
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_UNSUPPORTED:
+ {
+ nrf_drv_usbd_ep_stall_clear(ep_out_addr_get(p_inst));
+ /*Unsupported command handle: status stage*/
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Unexpected csw_wait_start on ep clear: %d", ret);
+ }
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DEVICE_ERROR:
+ {
+ nrf_drv_usbd_ep_stall_clear(ep_out_addr_get(p_inst));
+ /*Unsupported command handle: status stage*/
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PE);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Unexpected csw_wait_start on ep clear: %d", ret);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ return ret;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP class IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_MSC_REQ_GET_MAX_LUN:
+ {
+
+ if (p_setup_ev->setup.wValue.w != 0)
+ {
+ break;
+ }
+
+ if (p_setup_ev->setup.wLength.w != 1)
+ {
+ break;
+ }
+
+ size_t tx_size;
+ uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+ ASSERT(p_msc->specific.inst.block_devs_count != 0);
+ p_tx_buff[0] = p_msc->specific.inst.block_devs_count - 1;
+
+ ret_code_t ret = cbw_wait_start(p_inst);
+ UNUSED_VARIABLE(ret);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint8_t));
+ }
+
+ default:
+ break;
+
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP class OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_MSC_REQ_BULK_RESET:
+ {
+ if (p_setup_ev->setup.wValue.w != 0)
+ {
+ break;
+ }
+
+ if (p_setup_ev->setup.wLength.w != 0)
+ {
+ break;
+ }
+
+ /*
+ * Reset internal state to be ready for next CBW
+ */
+ NRF_LOG_DEBUG("bulk ep reset");
+ bulk_ep_reset(p_inst);
+
+ if (p_msc_ctx->state != APP_USBD_MSC_STATE_CBW)
+ {
+ ret_code_t ret = cbw_wait_start(p_inst);
+ UNUSED_VARIABLE(ret);
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Control endpoint handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Handle read6/read10 command data stage
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t state_data_in_handle(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ p_msc_ctx->current.trans_in_progress = false;
+ APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, p_msc_ctx->current.trans_req_id);
+
+ if (p_msc_ctx->current.blk_datasize == 0 && p_msc_ctx->current.req_busy_mask == 0)
+ {
+ p_msc_ctx->current.blk_idx = p_msc_ctx->current.blk_size = 0;
+ ret = csw_wait_start(p_inst, p_msc_ctx->current.csw_status);
+ return ret;
+ }
+
+ ASSERT(p_msc_ctx->current.blk_size != 0);
+
+ if (p_msc_ctx->current.req_busy_mask == 0)
+ {
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun];
+
+ /*Trigger new block read request*/
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ uint32_t req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos);
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos));
+
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ ret = nrf_blk_dev_read_req(p_blkd, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: ret: %u", ret);
+ return ret;
+ }
+
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+ p_msc_ctx->current.trans_req_id ^= 1;
+
+ nrf_block_req_t * p_req = &p_msc_ctx->current.req;
+ if (p_req->p_buff == NULL)
+ {
+ p_msc_ctx->current.trans_req_id ^= 1;
+ return NRF_SUCCESS;
+ }
+
+ ret = transfer_in_start(p_inst,
+ p_req->p_buff,
+ p_req->blk_count * blk_size,
+ APP_USBD_MSC_STATE_DATA_IN);
+
+ if (ret == NRF_SUCCESS)
+ {
+ /*Clear processed block request.*/
+ memset(p_req, 0, sizeof(nrf_block_req_t));
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Endpoint IN event handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("state: %d, ep in event, status: %d",
+ p_msc_ctx->state,
+ p_event->drv_evt.data.eptransfer.status);
+
+ if (p_event->drv_evt.data.eptransfer.status != NRF_USBD_EP_OK)
+ {
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_CMD_IN:
+ {
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DATA_IN:
+ {
+ ret = state_data_in_handle(p_inst);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_CSW:
+ {
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DATA_OUT:
+ {
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_UNSUPPORTED:
+ {
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ default:
+ {
+ ret = NRF_ERROR_INTERNAL;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Helper function to calculate next block transfer block count
+ *
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ *
+ * @return Blocks to transfer
+ * */
+static uint32_t next_transfer_blkcnt_calc(app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ uint32_t blkcnt = p_msc->specific.inst.block_buff_size / p_msc_ctx->current.blk_size;
+
+ if (blkcnt > (p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size))
+ {
+ blkcnt = p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size;
+ }
+
+ return blkcnt;
+}
+
+
+/**
+ * @brief Helper function to calculate next transfer size
+ *
+ * @param[in] p_msc_ctx MSC context
+ *
+ * @return Blocks to transfer
+ * */
+static uint32_t next_transfer_size_calc(app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ uint32_t blk_cnt = p_msc_ctx->current.blk_count;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ return p_msc_ctx->current.blk_datasize > blk_size * blk_cnt ?
+ blk_size * blk_cnt : p_msc_ctx->current.blk_datasize;
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_TESTUNITREADY handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_testunitready(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: TESTUNITREADY");
+ if (uint32_decode(p_msc_ctx->cbw.datlen) != 0)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.cdb_length != APP_USBD_SCSI_CMD_TESTUNITREADY_LEN)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_REQUESTSENSE handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_requestsense(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: REQUESTSENSE");
+ app_usbd_scsi_cmd_requestsense_t const * p_reqs = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_reqs);
+
+ if ((p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_requestsense_t)))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_requestsense_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ if (p_msc_ctx->resp_len == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ }
+
+ memset(&p_msc_ctx->scsi_resp, 0, sizeof(app_usbd_scsi_cmd_requestsense_resp_t));
+ p_msc_ctx->scsi_resp.requestsense.code = APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID |
+ APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT;
+
+ p_msc_ctx->scsi_resp.requestsense.len = sizeof(app_usbd_scsi_cmd_requestsense_resp_t) -
+ offsetof(app_usbd_scsi_cmd_requestsense_resp_t, len);
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_FORMAT_UNIT handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_formatunit(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: FORMAT_UNIT");
+ return status_unsupported_start(p_inst);
+}
+
+
+static ret_code_t cmd_read_start(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.trans_in_progress = false;
+ p_msc_ctx->current.req_busy_mask = 0;
+ p_msc_ctx->current.workbuff_pos = 0;
+
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, 0);
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos));
+
+ NRF_LOG_DEBUG("cmd_read_start");
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ ret_code_t ret = nrf_blk_dev_read_req(p_blkd, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: ret: %u", ret);
+
+ return ret;
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_read6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: READ6");
+ app_usbd_scsi_cmd_read6_t const * p_read6 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read6_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = ((p_read6->mslba & 0x1F) << 16) |
+ uint16_big_decode(p_read6->lslba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_read6->xfrlen)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * p_read6->xfrlen;
+ }
+
+ return cmd_read_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+static ret_code_t cmd_write_start(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("cmd_write_start");
+ ret_code_t ret = transfer_out_start(p_inst,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos),
+ next_transfer_size_calc(p_msc_ctx),
+ APP_USBD_MSC_STATE_DATA_OUT);
+
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->current.trans_req_id = 0;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask,
+ p_msc_ctx->current.trans_req_id);
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_write6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: WRITE6");
+ app_usbd_scsi_cmd_write6_t const * p_write6 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write6_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = (p_write6->mslba & 0x1F << 16) |
+ uint16_big_decode(p_write6->lslba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_write6->xfrlen)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * p_write6->xfrlen;
+ }
+
+ return cmd_write_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_INQUIRY handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_inquiry(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: INQUIRY");
+ app_usbd_scsi_cmd_inquiry_t const * p_inq = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_inq->pagecode != 0)
+ {
+ NRF_LOG_WARNING("unsupported pagecode");
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ NRF_LOG_WARNING("unsupported LUN");
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_inquiry_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ if (p_msc_ctx->resp_len == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ }
+
+
+ p_msc_ctx->scsi_resp.inquiry.qualtype = APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED |
+ APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS;
+ p_msc_ctx->scsi_resp.inquiry.flags1 = APP_USBD_MSC_SCSI_INQ_FLAG1_RMB;
+ p_msc_ctx->scsi_resp.inquiry.version = APP_USBD_SCSI_INQ_VER_SPC4;
+ p_msc_ctx->scsi_resp.inquiry.flags2 = APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 |
+ APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP;
+ p_msc_ctx->scsi_resp.inquiry.len = sizeof(app_usbd_scsi_cmd_inquiry_resp_t) -
+ offsetof(app_usbd_scsi_cmd_inquiry_resp_t, len);
+
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+ nrf_block_dev_info_strings_t * p_strings = NULL;
+ UNUSED_RETURN_VALUE(nrf_blk_dev_ioctl(p_blkd,
+ NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS,
+ &p_strings));
+
+ if (p_strings)
+ {
+ UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.vendorid,
+ p_strings->p_vendor,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid)));
+
+ UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.productid,
+ p_strings->p_product,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.productid)));
+
+ UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.revision,
+ p_strings->p_revision,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.revision)));
+ }
+ else
+ {
+ memset(p_msc_ctx->scsi_resp.inquiry.vendorid,
+ 0,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid));
+ memset(p_msc_ctx->scsi_resp.inquiry.productid,
+ 0,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.productid));
+ memset(p_msc_ctx->scsi_resp.inquiry.revision,
+ 0,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.revision));
+ }
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modeselect6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESELECT6");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modesense6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESENSE6");
+ app_usbd_scsi_cmd_modesense6_t const * p_sense6 = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_sense6);
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense6_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_modesense6_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ app_usbd_scsi_cmd_modesense6_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense6;
+ p_resp->mdlen = sizeof(app_usbd_scsi_cmd_modesense6_resp_t) - 1;
+ p_resp->type = 0;
+ p_resp->param = 0;
+ p_resp->bdlen = 0;
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_STARTSTOPUNIT handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_startstopunit(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: STARTSTOPUNIT");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_SENDDIAGNOSTIC handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_senddiagnostic(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: SENDDIAGNOSTIC");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_preventremoval(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: PREVENTMEDIAREMOVAL");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READCAPACITY10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_readcapacity10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: READCAPACITY10");
+
+ app_usbd_scsi_cmd_readcapacity10_t const * p_cap10 = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_cap10);
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_readcapacity10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ if (p_msc_ctx->resp_len == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ }
+
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+ nrf_block_dev_geometry_t const * p_geometry = nrf_blk_dev_geometry(p_blkd);
+
+ (void)uint32_big_encode(p_geometry->blk_count - 1, p_msc_ctx->scsi_resp.readcapacity10.lba);
+ (void)uint32_big_encode(p_geometry->blk_size, p_msc_ctx->scsi_resp.readcapacity10.blklen);
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_read10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: READ10");
+ app_usbd_scsi_cmd_read10_t const * p_read10 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ }
+
+ if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) == 0)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = uint32_big_decode(p_read10->lba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ uint16_t blocks = uint16_big_decode(p_read10->xfrlen);
+ p_msc_ctx->current.csw_status =
+ uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ?
+ APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS;
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * blocks;
+ }
+
+ return cmd_read_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_write10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: WRITE10");
+ app_usbd_scsi_cmd_write10_t const * p_write10 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ }
+
+
+ if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) != 0)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = uint32_big_decode(p_write10->lba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ uint16_t blocks = uint16_big_decode(p_write10->xfrlen);
+ p_msc_ctx->current.csw_status =
+ uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ?
+ APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS;
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * blocks;
+ }
+
+ return cmd_write_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modeselect10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESELECT10");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modesense10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESENSE10");
+ app_usbd_scsi_cmd_modesense10_t const * p_sense10 = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_sense10);
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_modesense6_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ app_usbd_scsi_cmd_modesense10_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense10;
+
+ memset(p_resp, 0, sizeof(app_usbd_scsi_cmd_modesense10_resp_t));
+ uint16_t len = sizeof(app_usbd_scsi_cmd_modesense10_resp_t) - sizeof(p_resp->mdlen);
+ p_resp->mdlen[1] = len & 0xff;
+ p_resp->mdlen[0] = (len >> 8) & 0xff;
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief Get the size of the last OUT transfer
+ *
+ * @param p_inst Generic class instance
+ *
+ * @return Number of received bytes or 0 if none.
+ */
+static size_t get_last_out_size(app_usbd_class_inst_t const * p_inst)
+{
+ nrf_drv_usbd_ep_t ep = ep_out_addr_get(p_inst);
+ size_t size;
+ ret_code_t ret = nrf_drv_usbd_ep_status_get(ep, &size);
+
+ if (ret != NRF_SUCCESS)
+ {
+ size = 0;
+ }
+
+ return size;
+}
+
+
+/**
+ * @brief SCSI Command Block Wrapper handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @return Standard error code
+ * */
+static ret_code_t state_cbw(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ memset(&p_msc_ctx->current, 0, sizeof(p_msc_ctx->current));
+
+ /*Verify the transfer size*/
+ if (get_last_out_size(p_inst) != sizeof(app_usbd_msc_cbw_t))
+ {
+ NRF_LOG_DEBUG("CMD: size error: %u", get_last_out_size(p_inst));
+ status_cbwinvalid_start(p_inst);
+ return NRF_SUCCESS;
+ }
+
+ /*Verify CBW signature*/
+ if (memcmp(p_msc_ctx->cbw.signature,
+ APP_USBD_MSC_CBW_SIGNATURE,
+ sizeof(p_msc_ctx->cbw.signature)) != 0)
+ {
+ NRF_LOG_DEBUG("CMD: header error: 0x%02x%02x%02x%02x",
+ p_msc_ctx->cbw.signature[0], p_msc_ctx->cbw.signature[1],
+ p_msc_ctx->cbw.signature[2], p_msc_ctx->cbw.signature[3]);
+
+ status_cbwinvalid_start(p_inst);
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_msc_ctx->cbw.cdb[0])
+ {
+ case APP_USBD_SCSI_CMD_TESTUNITREADY:
+ ret = cmd_testunitready(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_REQUESTSENSE:
+ ret = cmd_requestsense(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_FORMAT_UNIT:
+ ret = cmd_formatunit(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_READ6:
+ ret = cmd_read6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_WRITE6:
+ ret = cmd_write6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_INQUIRY:
+ ret = cmd_inquiry(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESELECT6:
+ ret = cmd_modeselect6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESENSE6:
+ ret = cmd_modesense6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_STARTSTOPUNIT:
+ ret = cmd_startstopunit(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_SENDDIAGNOSTIC:
+ ret = cmd_senddiagnostic(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL:
+ ret = cmd_preventremoval(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_READCAPACITY10:
+ ret = cmd_readcapacity10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_READ10:
+ ret = cmd_read10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_WRITE10:
+ ret = cmd_write10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESELECT10:
+ ret = cmd_modeselect10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESENSE10:
+ ret = cmd_modesense10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ default:
+ NRF_LOG_DEBUG("CMD: UNSUPPORTED");
+ NRF_LOG_HEXDUMP_DEBUG(&(p_msc_ctx->cbw), sizeof(p_msc_ctx->cbw));
+ if (uint32_decode(p_msc_ctx->cbw.datlen) != 0)
+ {
+ ret = status_unsupported_start(p_inst);
+ }
+ else
+ {
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ }
+ break;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Handle write6/write10 command data stage
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t state_data_out_handle(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ ret_code_t ret = NRF_SUCCESS;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ NRF_LOG_DEBUG("APP_USBD_MSC_STATE_DATA_OUT");
+
+ p_msc_ctx->current.trans_in_progress = false;
+ if ((p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) &&
+ (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size))
+ {
+ size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size;
+ if (size > p_msc_ctx->current.blk_count * blk_size)
+ {
+ size = p_msc_ctx->current.blk_count * blk_size;
+ }
+
+ if (size)
+ {
+ ret = transfer_out_start(p_inst,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos),
+ size,
+ APP_USBD_MSC_STATE_DATA_OUT);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->current.trans_req_id ^= 1;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask,
+ p_msc_ctx->current.trans_req_id);
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+ }
+ }
+
+ if (!p_msc_ctx->current.block_req_in_progress)
+ {
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun];
+
+ size_t pos = p_msc_ctx->current.workbuff_pos;
+ if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK)
+ {
+ pos ^= p_msc->specific.inst.block_buff_size;
+ }
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff + pos));
+
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ p_msc_ctx->current.block_req_in_progress = true;
+ ret = nrf_blk_dev_write_req(p_blkd, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: ret: %u", ret);
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Endpoint OUT event handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("state: %d, ep out event, status: %d",
+ p_msc_ctx->state,
+ p_event->drv_evt.data.eptransfer.status);
+
+ ret_code_t ret = NRF_SUCCESS;
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_WAITING)
+ {
+ if (p_msc_ctx->state == APP_USBD_MSC_STATE_DATA_OUT)
+ {
+ NRF_LOG_DEBUG("NRF_USBD_EP_WAITING");
+ }
+ else if (p_msc_ctx->state == APP_USBD_MSC_STATE_CSW ||
+ p_msc_ctx->state == APP_USBD_MSC_STATE_IDLE)
+ {
+ ret = cbw_wait_start(p_inst);
+ }
+
+ return ret;
+ }
+ else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_ABORTED)
+ {
+ p_msc_ctx->state = APP_USBD_MSC_STATE_IDLE;
+ return NRF_SUCCESS;
+ }
+ else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OVERLOAD)
+ {
+ NRF_LOG_ERROR("Data overload");
+
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_DATA_OUT:
+ {
+ status_deverror_start(p_inst);
+ }
+
+ /* Default action is the same like CBW - stall totally until bulk reset */
+ case APP_USBD_MSC_STATE_CBW:
+ default:
+ {
+ status_cbwinvalid_start(p_inst);
+ }
+ }
+ return NRF_SUCCESS;
+ }
+ else /*NRF_USBD_EP_OK*/
+ {
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_CBW:
+ {
+ ret = state_cbw(p_inst);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_CMD_OUT:
+ {
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DATA_OUT:
+ {
+ CRITICAL_REGION_ENTER();
+ ret = state_data_out_handle(p_inst);
+ CRITICAL_REGION_EXIT();
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_UNSUPPORTED:
+ {
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_CSW:
+ break;
+
+ default:
+ {
+ ASSERT(0);
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+ }
+ }
+
+ NRF_LOG_DEBUG("Ep proc status: %d", ret);
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t msc_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ UNUSED_VARIABLE(p_msc);
+ UNUSED_VARIABLE(p_msc_ctx);
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+
+ case APP_USBD_EVT_DRV_RESET:
+ break;
+
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ ret = endpoint_in_event_handler(p_inst, p_event);
+ }
+ else
+ {
+ ret = endpoint_out_event_handler(p_inst, p_event);
+ }
+
+ break;
+
+ case APP_USBD_EVT_DRV_SUSPEND:
+ {
+ /*Flush all block devices cache on suspend*/
+
+ for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i];
+ (void)nrf_blk_dev_ioctl(p_blkd, NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH, NULL);
+ }
+
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+
+ case APP_USBD_EVT_INST_APPEND:
+ {
+ /*Verify serial number string*/
+ uint16_t const * p_serial_str = app_usbd_string_desc_get(APP_USBD_STRING_ID_SERIAL, 0);
+ if (p_serial_str == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ size_t len = app_usbd_string_desc_length(p_serial_str) / sizeof(uint16_t);
+ if (len < APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ for (size_t i = 1; i < len; ++i)
+ {
+ if (isxdigit(p_serial_str[i]) == 0)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ }
+
+ break;
+ }
+
+ case APP_USBD_EVT_INST_REMOVE:
+ {
+ break;
+ }
+
+ case APP_USBD_EVT_STARTED:
+ {
+ /*Initialize all block devices*/
+ ASSERT(p_msc->specific.inst.block_devs_count <= 16);
+
+ for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i];
+ ret = nrf_blk_dev_init(p_blk_dev, msc_blockdev_ev_handler, p_msc);
+ if (ret != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ p_msc_ctx->blk_dev_init_mask |= 1u << i;
+ ASSERT(nrf_blk_dev_geometry(p_blk_dev)->blk_size <=
+ p_msc->specific.inst.block_buff_size);
+ }
+
+ break;
+ }
+
+ case APP_USBD_EVT_STOPPED:
+ {
+ /*Un-initialize all block devices*/
+ ASSERT(p_msc->specific.inst.block_devs_count <= 16);
+ size_t i;
+
+ for (i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i];
+ ret = nrf_blk_dev_uninit(p_blk_dev);
+ if (ret != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ p_msc_ctx->blk_dev_init_mask &= ~(1u << i);
+ }
+
+ break;
+ }
+
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::feed_descriptors
+ */
+
+static bool msc_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_MSC_CLASS); // bInterfaceClass = MSC
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_msc->specific.inst.subclass); // bInterfaceSubclass (Industry Standard Command Block)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_msc->specific.inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ static uint8_t j = 0;
+
+ for (j = 0; j < endpoints; j++)
+ {
+ // ENDPOINT DESCRIPTOR
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterval
+ }
+
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+const app_usbd_class_methods_t app_usbd_msc_class_methods = {
+ .event_handler = msc_event_handler,
+ .feed_descriptors = msc_feed_descriptors,
+};
+
+
+/**
+ * @brief Block device read done event handler.
+ *
+ * @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE
+ *
+ * @param p_blk_dev Block device handle
+ * @param p_event Block device event
+ *
+ * */
+static void msc_blockdev_read_done_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event)
+{
+ ret_code_t ret;
+
+ app_usbd_class_inst_t const * p_inst = p_event->p_context;
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ uint32_t blk_cnt = p_msc_ctx->current.blk_count;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ /*Save actual request*/
+ size_t req_pos = (p_msc_ctx->current.workbuff_pos != 0) ? 1 : 0;
+
+ p_msc_ctx->current.req = *p_event->p_blk_req;
+
+ p_msc_ctx->current.block_req_in_progress = false;
+
+ /*Decrement transfer counter*/
+ p_msc_ctx->current.blk_idx += blk_cnt;
+ if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt)
+ {
+ p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt;
+ }
+ else
+ {
+ p_msc_ctx->current.blk_datasize = 0;
+ }
+
+ NRF_LOG_DEBUG("read_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u",
+ (uint32_t)p_event->p_blk_req->p_buff,
+ p_event->p_blk_req->blk_count,
+ p_msc_ctx->current.blk_datasize,
+ req_pos);
+
+ /*Calculate next block request size*/
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ if (!p_msc_ctx->current.trans_in_progress)
+ {
+ /*Trigger new transfer.*/
+ p_msc_ctx->current.trans_req_id = req_pos;
+ nrf_block_req_t * p_req = &p_msc_ctx->current.req;
+
+ ret = transfer_in_start(p_inst,
+ p_req->p_buff,
+ p_req->blk_count * blk_size,
+ APP_USBD_MSC_STATE_DATA_IN);
+ if (ret != NRF_SUCCESS)
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+ else
+ {
+ /*Clear processed block request.*/
+ memset(p_req, 0, sizeof(nrf_block_req_t));
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+
+ }
+
+ if (p_msc_ctx->current.req_busy_mask == APP_USBD_MSC_REQ_BUSY_FULL_MASK)
+ {
+ /* No need to perform next block read request. USB transfers need to catch-up
+ * block device readings */
+ return;
+ }
+
+ if (p_msc_ctx->current.blk_count == 0)
+ {
+ /*All data has been read. No need to trigger new block request.*/
+ return;
+ }
+
+ /*Trigger new block read request*/
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0;
+
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos);
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos));
+
+
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ ret = nrf_blk_dev_read_req(p_blk_dev, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: ret: %u", ret);
+
+ if (ret != NRF_SUCCESS)
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+}
+
+
+/**
+ * @brief Block device write done event handler.
+ *
+ * @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE
+ *
+ * @param p_blk_dev Block device handle
+ * @param p_event Block device event
+ *
+ * */
+static void msc_blockdev_write_done_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event)
+{
+ app_usbd_class_inst_t const * p_inst = p_event->p_context;
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ uint32_t blk_cnt = p_msc_ctx->current.blk_count;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ /*Save actual request*/
+ size_t req_pos = (p_event->p_blk_req->p_buff == p_msc->specific.inst.p_block_buff) ? 0 : 1;
+
+ p_msc_ctx->current.req = *p_event->p_blk_req;
+
+ APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, req_pos);
+ p_msc_ctx->current.block_req_in_progress = false;
+
+ p_msc_ctx->current.blk_idx += blk_cnt;
+
+ if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt)
+ {
+ p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt;
+ }
+ else
+ {
+ p_msc_ctx->current.blk_datasize = 0;
+ }
+
+ NRF_LOG_DEBUG("write_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u",
+ (uint32_t)p_event->p_blk_req->p_buff,
+ p_event->p_blk_req->blk_count,
+ p_msc_ctx->current.blk_datasize,
+ req_pos);
+
+ if (p_msc_ctx->current.blk_datasize == 0)
+ {
+ p_msc_ctx->current.blk_idx = p_msc_ctx->current.blk_size = 0;
+ UNUSED_RETURN_VALUE(csw_wait_start(p_inst, p_msc_ctx->current.csw_status));
+ return;
+ }
+
+ if (p_msc_ctx->current.blk_datasize <= p_msc_ctx->current.blk_count * blk_size)
+ {
+ size_t pos = p_msc_ctx->current.workbuff_pos;
+ if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK)
+ {
+ pos ^= p_msc->specific.inst.block_buff_size;
+ }
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff + pos));
+
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ p_msc_ctx->current.block_req_in_progress = true;
+ ret_code_t ret = nrf_blk_dev_write_req(p_blk_dev, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: ret: %u", ret);
+
+ if (ret != NRF_SUCCESS)
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+
+ return;
+ }
+
+ if (!p_msc_ctx->current.trans_in_progress &&
+ (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size))
+ {
+ size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size;
+ if (size > p_msc_ctx->current.blk_count * blk_size)
+ {
+ size = p_msc_ctx->current.blk_count * blk_size;
+ }
+
+ if (size > 0)
+ {
+ /*Trigger new transfer.*/
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+ ret_code_t ret = transfer_out_start(p_inst,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos),
+ size,
+ APP_USBD_MSC_STATE_DATA_OUT);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->current.trans_req_id ^= 1;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask,
+ p_msc_ctx->current.trans_req_id);
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+ else
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Block device event handler.
+ *
+ * Mass storage block device event handler. Need to be pined to all block devices
+ * from initializer list.
+ *
+ * @param p_blk_dev Block device handle
+ * @param p_event Block device event
+ *
+ * */
+static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event)
+{
+ switch (p_event->ev_type)
+ {
+ case NRF_BLOCK_DEV_EVT_INIT:
+ break;
+
+ case NRF_BLOCK_DEV_EVT_UNINIT:
+ break;
+
+ case NRF_BLOCK_DEV_EVT_BLK_READ_DONE:
+ CRITICAL_REGION_ENTER();
+ msc_blockdev_read_done_handler(p_blk_dev, p_event);
+ CRITICAL_REGION_EXIT();
+ break;
+
+ case NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE:
+ CRITICAL_REGION_ENTER();
+ msc_blockdev_write_done_handler(p_blk_dev, p_event);
+ CRITICAL_REGION_EXIT();
+ break;
+
+ default:
+ break;
+ }
+}
+
+/** @} */
+
+bool app_usbd_msc_sync(app_usbd_msc_t const * p_msc)
+{
+ bool rc = true;
+ ret_code_t ret = NRF_SUCCESS;
+
+ for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i];
+ bool flush_in_progress = true;
+
+ ret = nrf_blk_dev_ioctl(p_blkd,
+ NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH,
+ &flush_in_progress);
+
+ if ((ret != NRF_SUCCESS) || flush_in_progress)
+ {
+ rc = false;
+ }
+ }
+
+ return rc;
+}
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_MSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h
new file mode 100644
index 0000000..b7fcb6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_MSC_H__
+#define APP_USBD_MSC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "nrf_block_dev.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_msc_types.h"
+#include "app_usbd_msc_desc.h"
+#include "app_usbd_msc_scsi.h"
+#include "app_usbd_msc_internal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc USB MSC class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the USB MSC class.
+ *
+ * @details References:
+ * - "Universal Serial Bus Mass Storage Class, Specification Overview,"
+ * Revision 1.2, USB Implementer's Forum, June 23, 2003.
+ * - "Universal Serial Bus Mass Storage Class, Bulk-Only Transport,"
+ * Revision 1.0, USB Implementer's Forum, September 31, 1999.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Mass storage class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_msc_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_msc, \
+ APP_USBD_MSC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \
+ APP_USBD_MSC_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_MSC_DATA_SPECIFIC_DEC \
+);
+#endif
+
+/*lint -restore*/
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler
+ *
+ * @note Example prototype of user event handler:
+ *
+ * void msc_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ * app_usbd_msc_user_event_t event);
+ */
+typedef enum app_usbd_msc_user_event_e {
+ APP_USBD_MSC_USER_EVT_NONE, /**< Dummy event to satisfy compilers. */
+} app_usbd_msc_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Helper macro for defining MSC endpoints
+ *
+ * @param in_number Input endpoint number
+ * @param out_number Output endpoint number
+ * */
+#define APP_USBD_MSC_ENDPOINT_LIST(in_number, out_number) ( \
+ CONCAT_2(NRF_DRV_USBD_EPIN, in_number), \
+ CONCAT_2(NRF_DRV_USBD_EPOUT, out_number) \
+)
+
+/**
+ * @brief Global definition of app_usbd_msc_t class
+ *
+ * @param instance_name Name of global instance
+ * @param interface_number Unique interface number
+ * @param user_ev_handler User event handler (optional)
+ * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t)
+ * @param blockdev_list Block device list
+ * @param workbuffer_size Work buffer size (need to fit into all block devices from
+ * block device list)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_MSC_GLOBAL_DEF_INTERNAL
+ *
+ */
+#define APP_USBD_MSC_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ blockdev_list, \
+ workbuffer_size) \
+ APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ blockdev_list, \
+ workbuffer_size)
+
+
+/**
+ * @@brief Helper function to get class instance from MSC
+ *
+ * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF)
+ *
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_msc_class_inst_get(app_usbd_msc_t const * p_msc)
+{
+ return &p_msc->base;
+}
+
+/**
+ * @brief Helper function to get MSC from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ *
+ * @return MSC class handle
+ */
+static inline app_usbd_msc_t const * app_usbd_msc_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_msc_t const *)p_inst;
+}
+
+/**
+ * @brief Synchronization of all block devices pined to MSC
+ *
+ * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF)
+ *
+ * @retval true All block devices flushed data
+ * @retval false At least one block device has not flushed data
+ */
+bool app_usbd_msc_sync(app_usbd_msc_t const * p_msc);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h
new file mode 100644
index 0000000..83c3916
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_MSC_DESC_H__
+#define APP_USBD_MSC_DESC_H__
+
+#include "app_usbd_descriptor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_desc USB MSC descriptors
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 Descriptors for the USB MSC class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for MSC class
+ *
+ * @param interface_number Interface number
+ * @param subclass Subclass, @ref app_usbd_msc_subclass_t
+ * @param protocol Protocol, @ref app_usbd_msc_protocol_t
+ * */
+#define APP_USBD_MSC_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 2, \
+ /*.bInterfaceClass = */ APP_USBD_MSC_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of endpoint descriptors for MSC class
+ *
+ * @param endpoint_in IN endpoint
+ * @param endpoint_out OUT endpoint
+ * @param ep_size Endpoint size
+ * */
+#define APP_USBD_MSC_EP_DSC(endpoint_in, endpoint_out, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_out, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h
new file mode 100644
index 0000000..c7036fa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_MSC_INTERNAL_H__
+#define APP_USBD_MSC_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_internals USB MSC internals
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 Internals of the USB MSC class.
+ * @{
+ */
+
+/**
+ * @brief Minimal serial string descriptor length
+ * */
+#define APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE (12 + 1)
+
+/**
+ * @brief Forward declaration of Mass Storage Class type
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_msc);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_msc_user_event_e
+ *
+ */
+enum app_usbd_msc_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event User event
+ *
+ * */
+typedef void (*app_usbd_msc_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_msc_user_event_e event);
+
+/**
+ * @brief MSC part of class instance data
+ */
+typedef struct {
+ void * p_block_buff; //!< Block buffer
+ size_t block_buff_size; //!< Block buffer size (typically 512 bytes)
+
+ nrf_block_dev_t const ** pp_block_devs; //!< Block devices list
+ size_t block_devs_count; //!< Block device list size
+
+ app_usbd_msc_user_ev_handler_t user_ev_handler; //!< User event handler
+
+ app_usbd_msc_subclass_t subclass; //!< MSC subclass
+ app_usbd_msc_protocol_t protocol; //!< MSC protocol
+} app_usbd_msc_inst_t;
+
+/**
+ * @brief Internal module state
+ */
+typedef enum {
+ APP_USBD_MSC_STATE_DISABLED, /**< Internal module state DISABLED */
+ APP_USBD_MSC_STATE_IDLE, /**< Internal module state IDLE */
+ APP_USBD_MSC_STATE_CBW, /**< Internal module state CBW */
+ APP_USBD_MSC_STATE_CMD_IN, /**< Internal module state CMD_IN */
+ APP_USBD_MSC_STATE_CMD_OUT, /**< Internal module state CMD_OUT */
+ APP_USBD_MSC_STATE_DATA_IN, /**< Internal module state DATA_IN */
+ APP_USBD_MSC_STATE_DATA_OUT, /**< Internal module state DATA_OUT */
+ APP_USBD_MSC_STATE_DATA_OUT_WAIT, /**< Internal module state DATA_OUT_WAIT */
+ APP_USBD_MSC_STATE_CSW, /**< Internal module state CSW */
+ APP_USBD_MSC_STATE_UNSUPPORTED, /**< Internal module state UNSUPPORTED */
+ APP_USBD_MSC_STATE_CBW_INVALID, /**< Endpoint is stalled until
+ * the command @ref APP_USBD_MSC_REQ_BULK_RESET */
+ APP_USBD_MSC_STATE_DEVICE_ERROR, /**< Endpoint is stalled and it is required
+ * to send PE error when clearing */
+} app_usbd_msc_state_t;
+
+/**
+ * @brief MSC context
+ *
+ * */
+typedef struct {
+ app_usbd_msc_cbw_t cbw; //!< SCSI command block wrapper
+ app_usbd_msc_csw_t csw; //!< SCSI Command status wrapper
+
+ app_usbd_msc_state_t state; //!< Internal module state
+
+ struct {
+ uint8_t lun; //!< Current transfer blocks: logical unit
+ uint8_t csw_status; //!< Current CSW status
+ uint32_t blk_idx; //!< Current transfer: block index
+ uint32_t blk_datasize; //!< Current transfer: data size to transfer
+ uint32_t blk_size; //!< Current transfer: block size
+ uint32_t blk_count; //!< Current transfer: block count
+ uint32_t residue; //!< @ref app_usbd_msc_csw_t::residue
+
+ bool trans_in_progress; //!< Transfer in progress flag
+ bool block_req_in_progress; //!< Block request in progress flag
+ size_t workbuff_pos; //!< Current buffer offset (double buffering mode)
+ uint8_t req_busy_mask; //!< Request bust mask (double buffering mode)
+ uint8_t trans_req_id; //!< Current transfered request (double buffering mode)
+
+ nrf_block_req_t req; //!< Last processed block req (double buffering mode)
+ } current;
+
+ size_t resp_len; //!< Response length
+
+ /*SCSI response container*/
+ union {
+ app_usbd_scsi_cmd_inquiry_resp_t inquiry; //!< @ref APP_USBD_SCSI_CMD_INQUIRY response
+ app_usbd_scsi_cmd_requestsense_resp_t requestsense; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE response
+ app_usbd_scsi_cmd_readcapacity10_resp_t readcapacity10; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10 response
+ app_usbd_scsi_cmd_modesense6_resp_t modesense6; //!< @ref APP_USBD_SCSI_CMD_MODESENSE6 response
+ app_usbd_scsi_cmd_modesense10_resp_t modesense10; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10 response
+ } scsi_resp;
+
+ uint16_t blk_dev_init_mask; //!< Block devices init mask
+} app_usbd_msc_ctx_t;
+
+
+/**
+ * @brief MSC configuration macro
+ *
+ * Used by @ref APP_USBD_MSC_GLOBAL_DEF
+ *
+ * @param iface Interface number
+ * @param endpoints Endpoint list
+ * */
+#define APP_USBD_MSC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints)))
+
+
+/**
+ * @brief Specific class constant data for MSC
+ *
+ * @ref app_usbd_msc_inst_t
+ */
+#define APP_USBD_MSC_INSTANCE_SPECIFIC_DEC app_usbd_msc_inst_t inst;
+
+/**
+ * @brief Configures MSC instance
+ *
+ * @param block_devs Block devices list
+ * @param block_buff Block buffer
+ * @param user_event_handler User event handler
+ */
+#define APP_USBD_MSC_INST_CONFIG(block_devs, block_buff, user_event_handler) \
+ .inst = { \
+ .pp_block_devs = block_devs, \
+ .block_devs_count = ARRAY_SIZE(block_devs), \
+ .p_block_buff = block_buff, \
+ .block_buff_size = sizeof(block_buff) / 2, \
+ .user_ev_handler = user_event_handler, \
+ .subclass = APP_USBD_MSC_SUBCLASS_TRANSPARENT, \
+ .protocol = APP_USBD_MSC_PROTOCOL_BULK, \
+ }
+
+/**
+ * @brief Specific class data for MSC
+ *
+ * @ref app_usbd_msc_ctx_t
+ * */
+#define APP_USBD_MSC_DATA_SPECIFIC_DEC app_usbd_msc_ctx_t ctx;
+
+
+/**
+ * @brief MSC descriptors config macro
+ *
+ * @param interface_number Interface number
+ * @param ... Extracted endpoint list
+ * */
+#define APP_USBD_MSC_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_MSC_INTERFACE_DSC(interface_number, \
+ APP_USBD_MSC_SUBCLASS_TRANSPARENT, \
+ APP_USBD_MSC_PROTOCOL_BULK) \
+ APP_USBD_MSC_EP_DSC(GET_VA_ARG_1(__VA_ARGS__), \
+ GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__)), \
+ 64) \
+}
+
+/**
+ * @brief Public MSC class interface
+ *
+ * */
+extern const app_usbd_class_methods_t app_usbd_msc_class_methods;
+
+/**
+ * @brief Global definition of mass storage class instance
+ */
+#define APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ blockdev_list, \
+ workbuffer_size) \
+ static const nrf_block_dev_t * CONCAT_2(instance_name, _blkdevs)[] = \
+ { BRACKET_EXTRACT(blockdev_list) }; \
+ static uint32_t CONCAT_2(instance_name, _block)[2 *(workbuffer_size) / sizeof(uint32_t)]; \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_msc, \
+ &app_usbd_msc_class_methods, \
+ APP_USBD_MSC_CONFIG(interface_number, endpoint_list), \
+ (APP_USBD_MSC_INST_CONFIG(CONCAT_2(instance_name, _blkdevs), \
+ CONCAT_2(instance_name, _block), \
+ user_ev_handler)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h
new file mode 100644
index 0000000..8379a8c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h
@@ -0,0 +1,329 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_MSC_SCSI_H__
+#define APP_USBD_MSC_SCSI_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_scsi USB MSC SCSI data structures
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 USB MSC SCSI data structures.
+ *
+ * @details Reference specifications:
+ * - "Reduced Block Commands (Revision 10a)" American National Standard
+ * for Information Technology, August 18, 1999
+ * - "SCSI Primary Commands - 4 (SPC-4)," American National Standard
+ * for Information Technology, July 19, 2008
+ * - "SCSI Block Commands -2 (SBC-2)," American National Standard
+ * for Information Technology, November 13, 2004
+ * - NuttX source code - Real-time Operating System: http://nuttx.org/
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * @{
+ */
+
+/**
+ * @brief SCSI command set
+ *
+ * Mandatory (and some optional) commands required by SBC-2.
+ *
+ */
+typedef enum {
+ APP_USBD_SCSI_CMD_TESTUNITREADY = 0x00, /**< TESTUNITREADY */
+ APP_USBD_SCSI_CMD_REQUESTSENSE = 0x03, /**< REQUESTSENSE */
+ APP_USBD_SCSI_CMD_FORMAT_UNIT = 0x04, /**< FORMAT_UNIT */
+ APP_USBD_SCSI_CMD_READ6 = 0x08, /**< READ6 */
+ APP_USBD_SCSI_CMD_WRITE6 = 0x0a, /**< WRITE6 */
+ APP_USBD_SCSI_CMD_INQUIRY = 0x12, /**< INQUIRY */
+ APP_USBD_SCSI_CMD_MODESELECT6 = 0x15, /**< MODESELECT6 */
+ APP_USBD_SCSI_CMD_MODESENSE6 = 0x1a, /**< MODESENSE6 */
+ APP_USBD_SCSI_CMD_STARTSTOPUNIT = 0x1b, /**< STARTSTOPUNIT */
+ APP_USBD_SCSI_CMD_SENDDIAGNOSTIC = 0x1d, /**< SENDDIAGNOSTIC */
+ APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL = 0x1e, /**< PREVENTMEDIAREMOVAL */
+ APP_USBD_SCSI_CMD_READCAPACITY10 = 0x25, /**< READCAPACITY10 */
+ APP_USBD_SCSI_CMD_READ10 = 0x28, /**< READ10 */
+ APP_USBD_SCSI_CMD_WRITE10 = 0x2a, /**< WRITE10 */
+ APP_USBD_SCSI_CMD_MODESELECT10 = 0x55, /**< MODESELECT10 */
+ APP_USBD_SCSI_CMD_MODESENSE10 = 0x5a, /**< MODESENSE10 */
+} app_usbd_scsi_cmd_t;
+
+
+#pragma pack(push, 1)
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE
+ uint8_t flags; //!< Flags
+ uint8_t reserved[2]; //!< Reserved
+ uint8_t alloclen; //!< Allocation length
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_requestsense_t;
+
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID 0x80 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT 0x70 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERRED 0x71 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENTDESC 0x72 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERREDDESC 0x73 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_FILEMARK 0x80 /**< Bits 7 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_EOM 0x40 /**< Bits 6 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILI 0x20 /**< Bits 5 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RESERVED 0x10 /**< Bits 4 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOSENSE 0x00 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RECOVEREDERROR 0x01 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOTREADY 0x02 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_MEDIUMERROR 0x03 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_HARDWAREERROR 0x04 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILLEGALREQUEST 0x05 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_UNITATTENTION 0x06 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_DATAPROTECT 0x07 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_BLANKCHECK 0x08 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_VENDORSPECIFIC 0x09 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ABORTEDCOMMAND 0x0b /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+
+
+#define APP_USBD_SCSI_CMD_TESTUNITREADY_LEN 6 /**< @ref APP_USBD_SCSI_CMD_TESTUNITREADY command length*/
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE response
+ */
+typedef struct {
+ uint8_t code; //!< Response code: APP_USBD_SCSI_CMD_REQSENSE_CODE_*
+ uint8_t obsolete; //!< Obsolete
+ uint8_t flags; //!< APP_USBD_SCSI_CMD_REQSENSE_FLAG_*
+ uint8_t info[4]; //!< Information
+ uint8_t len; //!< Additional length
+ uint8_t cmdinfo[4]; //!< Command-specific information
+ uint8_t code2; //!< Additional sense code
+ uint8_t qual2; //!< Additional sense code qualifier
+ uint8_t fru; //!< Field replacement unit code
+ uint8_t key[3]; //!< Sense key specific
+} app_usbd_scsi_cmd_requestsense_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_INQUIRY
+ uint8_t flags; //!< Command flags
+ uint8_t pagecode; //!< Page code
+ uint8_t alloclen[2]; //!< Allocation length
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_inquiry_t;
+
+#define APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED 0x00 /**< Peripheral connected */
+#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_CONN 0x20 /**< Peripheral not connected */
+#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_SUPP 0x60 /**< Peripheral not supported */
+
+#define APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS 0x00 /**< Direct Access (SBC) */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_SEQ_ACCESS 0x01 /**< Sequential Access */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_PRINTER 0x02 /**< Printer */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_PROCESSOR 0x03 /**< Processor device */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_WRITE_ONCE 0x04 /**< Write-once device */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_CD_DVD 0x05 /**< CD/DVD device */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_OPTICAL 0x07 /**< Optical Memory */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_MC 0x08 /**< Medium Changer */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_ARRAY 0x0c /**< Storage Array Controller */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_ENCLOSURE 0x0d /**< Enclosure Services */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_RBC 0x0e /**< Simplified Direct Access */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_OCRW 0x0f /**< Optical card reader/writer */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_BCC 0x10 /**< Bridge Controller Commands */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_OSD 0x11 /**< Object-based Storage */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_NONE 0x1f /**< No Peripheral */
+
+
+#define APP_USBD_MSC_SCSI_INQ_FLAG1_RMB 0x80 /**< Removable Medium */
+
+#define APP_USBD_SCSI_INQ_VER_NONE 0x00 /**< No standards conformance */
+#define APP_USBD_SCSI_INQ_VER_SPC 0x03 /**< SCSI Primary Commands (link to SBC) */
+#define APP_USBD_SCSI_INQ_VER_SPC2 0x04 /**< SCSI Primary Commands - 2 (link to SBC-2)*/
+#define APP_USBD_SCSI_INQ_VER_SPC3 0x05 /**< SCSI Primary Commands - 3 (link to SBC-2)*/
+#define APP_USBD_SCSI_INQ_VER_SPC4 0x06 /**< SCSI Primary Commands - 4 (link to SBC-3)*/
+
+#define APP_USBD_MSC_SCSI_INQ_FLAG2_NORMACA 0x20 /**< Normal ACA Supported */
+#define APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP 0x10 /**< Hierarchal LUN addressing */
+#define APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 0x02 /**< SPC-2 / SPC-3 response format*/
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY response
+ */
+typedef struct {
+ uint8_t qualtype; //!< Bits 5-7: Peripheral qualifier; Bits 0-4: Peripheral device type
+ uint8_t flags1; //!< Flags 1
+ uint8_t version; //!< Version
+ uint8_t flags2; //!< Flags 2
+ uint8_t len; //!< Additional length
+ uint8_t flags3; //!< Flags 3
+ uint8_t flags4; //!< Flags 4
+ uint8_t flags5; //!< Flags 5
+ uint8_t vendorid[8]; //!< T10 Vendor Identification
+ uint8_t productid[16]; //!< Product Identification
+ uint8_t revision[4]; //!< Product Revision Level
+} app_usbd_scsi_cmd_inquiry_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READ6 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ6
+ uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA)
+ uint8_t lslba[2]; //!< LS Logical Block Address (LBA)
+ uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_read6_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE6 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE6
+ uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA)
+ uint8_t lslba[2]; //!< LS Logical Block Address (LBA)
+ uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_write6_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 command
+ */
+typedef struct {
+ uint8_t opcode; //!<* @ref APP_USBD_SCSI_CMD_MODESENSE6
+ uint8_t flags; //!<* Flags
+ uint8_t pcpgcode; //!<* Bits 6-7: PC, bits 0-5: page code
+ uint8_t subpgcode; //!<* subpage code
+ uint8_t alloclen; //!<* Allocation length
+ uint8_t control; //!<* Control
+} app_usbd_scsi_cmd_modesense6_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 response
+ */
+typedef struct {
+ uint8_t mdlen; //!< Mode data length
+ uint8_t type; //!< Medium type
+ uint8_t param; //!< Device-specific parameter
+ uint8_t bdlen; //!< Block descriptor length
+} app_usbd_scsi_cmd_modesense6_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10
+ uint8_t reserved1; //!< Reserved field
+ uint8_t lba[4]; //!< Logical block address (LBA)
+ uint8_t reserved2[2]; //!< Reserved field
+ uint8_t pmi; //!< Bits 1-7 Reserved; Bit 0: PMI
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_readcapacity10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 response
+ */
+typedef struct {
+ uint8_t lba[4]; //!< Returned logical block address (LBA)
+ uint8_t blklen[4]; //!< Logical block length (in bytes)
+} app_usbd_scsi_cmd_readcapacity10_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READ10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ10
+ uint8_t flags; //!< Command flags
+ uint8_t lba[4]; //!< Logical Block Address (LBA)
+ uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number
+ uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_read10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE10
+ uint8_t flags; //!< Command flags
+ uint8_t lba[4]; //!< Logical Block Address (LBA)
+ uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number
+ uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_write10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10
+ uint8_t flags; //!< Flags
+ uint8_t pcpgcode; //!< Bits 6-7: PC, bits 0-5: page code
+ uint8_t subpgcode; //!< Subpage code
+ uint8_t reserved[3]; //!< Reserved
+ uint8_t alloclen[2]; //!< Allocation length
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_modesense10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 response
+ */
+typedef struct {
+ uint8_t mdlen[2]; //!< Mode data length
+ uint8_t type; //!< Medium type
+ uint8_t param; //!< Device-specific parameter
+ uint8_t reserved[2]; //!< Reserved
+ uint8_t bdlen[2]; //!< Block descriptor length
+} app_usbd_scsi_cmd_modesense10_resp_t;
+
+#pragma pack(pop)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_SCSI_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h
new file mode 100644
index 0000000..96a6431
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_MSC_TYPES_H__
+#define APP_USBD_MSC_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_types USB MSC types
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 Types used in the USB MSC class.
+ * @{
+ */
+
+/** @brief MSC class definition in interface descriptor
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_MSC_CLASS 0x08
+
+/**
+ * @brief MSC subclass possible value
+ */
+typedef enum {
+ APP_USBD_MSC_SUBCLASS_RBC = 0x01, /**< Reduced Block Commands */
+ APP_USBD_MSC_SUBCLASS_ATAPI = 0x02, /**< CD/DVD devices */
+ APP_USBD_MSC_SUBCLASS_QIC_157 = 0x03, /**< Tape devices */
+ APP_USBD_MSC_SUBCLASS_UFI = 0x04, /**< Floppy disk drives */
+ APP_USBD_MSC_SUBCLASS_SFF_8070I = 0x05, /**< Floppy disk drives */
+ APP_USBD_MSC_SUBCLASS_TRANSPARENT = 0x06, /**< Determined by INQUIRY */
+} app_usbd_msc_subclass_t;
+
+/**
+ * @brief MSC protocol possible value
+ *
+ * @note The USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport specification is approved
+ * for use only with full-speed floppy disk drives. CBI shall not be used in high-speed
+ * capable devices.
+ */
+typedef enum {
+ APP_USBD_MSC_PROTOCOL_CBI = 0x00, /**< Command/Bulk/Interrupt */
+ APP_USBD_MSC_PROTOCOL_CBI_ALT = 0x01, /**< W/o command completion */
+ APP_USBD_MSC_PROTOCOL_BULK = 0x50, /**< Bulk-only */
+} app_usbd_msc_protocol_t;
+
+/**
+ * @brief MSC USB requests @ref nrf_drv_usbd_setup_t::bmRequestType
+ *
+ * @note Requests are limited only to @ref APP_USBD_MSC_PROTOCOL_BULK protocol type.
+ */
+typedef enum {
+ APP_USBD_MSC_REQ_BULK_RESET = 0xFF, /**< Mass Storage Reset */
+ APP_USBD_MSC_REQ_GET_MAX_LUN = 0xFE, /**< Get Max LUN */
+} app_usbd_msc_req_t;
+
+#pragma pack(push, 1)
+
+#define APP_USBD_MSC_CBW_SIGNATURE "USBC" /**< CBW signature */
+#define APP_USBD_MSC_CBW_DIRECTION_IN (1u <<7) /**< CBW direction flag */
+
+/**
+ * @brief Command Block Wrapper (CBW)
+ */
+typedef struct {
+ uint8_t signature[4]; /**< "USBC" (hex: 0x43425355 little-endian) */
+ uint8_t tag[4]; /**< Unique command tag */
+ uint8_t datlen[4]; /**< Number of bytes that host expects to transfer */
+ uint8_t flags; /**< Bit 7: Direction=IN */
+ uint8_t lun; /**< Logical Unit Number, equals to @ref app_usbd_msc_inst_t :: block_devs_count*/
+ uint8_t cdb_length; /**< Length of cdb field */
+ uint8_t cdb[16]; /**< Command Data Block payload */
+} app_usbd_msc_cbw_t;
+
+#define APP_USBD_MSC_CSW_SIGNATURE "USBS" /**< CSW signature */
+
+#define APP_USBD_MSC_CSW_STATUS_PASS 0x00 /**< CSW status: Command Passed */
+#define APP_USBD_MSC_CSW_STATUS_FAIL 0x01 /**< CSW status: Command Failed */
+#define APP_USBD_MSC_CSW_STATUS_PE 0x02 /**< CSW status: Phase Error */
+
+/**
+ * @brief Command Status Wrapper (CSW)
+ */
+typedef struct {
+ uint8_t signature[4]; /**< "USBS" (hex: 0x53425355 little-endian) */
+ uint8_t tag[4]; /**< Unique command tag (@ref app_usbd_msc_cbw_t :: tag) */
+ uint8_t residue[4]; /**< Amount not transferred */
+ uint8_t status; /**< Status of transfer */
+} app_usbd_msc_csw_t;
+
+#pragma pack(pop)
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c
new file mode 100644
index 0000000..3716ec0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c
@@ -0,0 +1,374 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
+
+#include <string.h>
+#include <ctype.h>
+#include "app_usbd.h"
+#include "app_usbd_nrf_dfu_trigger.h"
+#include "app_usbd_string_desc.h"
+#include "nrf_gpio.h"
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger_internal USBD Nordic DFU Trigger internals
+ * @{
+ * @ingroup app_usbd_nrf_dfu_trigger
+ * @internal
+ */
+
+#define NRF_LOG_MODULE_NAME usbd_nrf_dfu_trigger
+
+#if APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR
+#else //APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**
+ * @brief Auxiliary function to access DFU Trigger instance data
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return DFU Trigger instance data @ref app_usbd_nrf_dfu_trigger_t
+ */
+static inline app_usbd_nrf_dfu_trigger_t const * nrf_dfu_trigger_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_nrf_dfu_trigger_t const *)p_inst;
+}
+
+/**
+ * @brief Auxiliary function to access DFU Trigger context data
+ *
+ * @param[in] p_dfu DFU Trigger instance data
+ *
+ * @return DFU Trigger context data @ref app_usbd_nrf_dfu_trigger_ctx_t
+ */
+static inline app_usbd_nrf_dfu_trigger_ctx_t * nrf_dfu_trigger_ctx_get(
+ app_usbd_nrf_dfu_trigger_t const * p_dfu)
+{
+ ASSERT(p_dfu != NULL);
+ ASSERT(p_dfu->specific.p_data != NULL);
+ return &p_dfu->specific.p_data->ctx;
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by DFU class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ * @retval NRF_ERROR_FORBIDDEN if endpoint stall cannot be cleared because of internal state
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ default:
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_nrf_dfu_trigger_user_event_t event)
+{
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+ if (p_dfu->specific.inst.user_ev_handler != NULL)
+ {
+ p_dfu->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Internal SETUP class IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_REQ_NORDIC_INFO:
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_nrf_dfu_trigger_nordic_info_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ p_dfu->specific.inst.p_dfu_info,
+ sizeof(app_usbd_nrf_dfu_trigger_nordic_info_t));
+
+ case APP_USBD_NRF_DFU_TRIGGER_REQ_SEM_VER:
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ p_dfu->specific.inst.p_sem_ver,
+ p_dfu->specific.inst.sem_ver_size);
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+ app_usbd_nrf_dfu_trigger_ctx_t * p_dfu_ctx = nrf_dfu_trigger_ctx_get(p_dfu);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_REQ_DETACH:
+ {
+ NRF_LOG_DEBUG("Entering DFU Mode");
+ p_dfu_ctx->state = APP_USBD_NRF_DFU_TRIGGER_STATE_DETACH;
+ user_event_handler(p_inst, APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH);
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Control endpoint handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t nrf_dfu_trigger_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *) p_event);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief @ref app_usbd_class_methods_t::feed_descriptors
+ */
+static bool nrf_dfu_trigger_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size)
+
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_descriptor_iface_t)); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_CLASS); // bInterfaceClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_SUBCLASS); // bInterfaceSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* FUNCTIONAL DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_nrf_dfu_trigger_desc_func_t)); // bFunctionLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_CS_FUNCTIONAL); // bDescriptorType
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_BIT_CAN_DNLOAD |
+ APP_USBD_NRF_DFU_TRIGGER_BIT_WILL_DETACH); // bmAttribute
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.detach_timeout)); // wDetachTimeOut LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.detach_timeout)); // wDetachTimeOut MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.transfer_size)); // wTransferSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.transfer_size)); // wTransferSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.bcd_dfu)); // bcdDFUVersion LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.bcd_dfu)); // bcdDFUVersion MSB
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+const app_usbd_class_methods_t app_usbd_nrf_dfu_trigger_class_methods = {
+ .event_handler = nrf_dfu_trigger_event_handler,
+ .feed_descriptors = nrf_dfu_trigger_feed_descriptors,
+};
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h
new file mode 100644
index 0000000..b15ea96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_NRF_DFU_TRIGGER_H__
+#define APP_USBD_NRF_DFU_TRIGGER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "nrf_block_dev.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_nrf_dfu_trigger_types.h"
+#include "app_usbd_nrf_dfu_trigger_internal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger USB Nordic DFU Trigger class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions,
+ * and API used by the USB Nordic DFU Trigger class.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Nordic DFU Trigger class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_nrf_dfu_trigger_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_NO_EP_TYPEDEF(app_usbd_nrf_dfu_trigger, \
+ APP_USBD_NRF_DFU_TRIGGER_CONFIG(0), \
+ APP_USBD_NRF_DFU_TRIGGER_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_NRF_DFU_TRIGGER_DATA_SPECIFIC_DEC \
+);
+#endif
+
+/*lint -restore*/
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler
+ *
+ * @note Example prototype of user event handler:
+ *
+ * void dfu_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ * app_usbd_nrf_dfu_trigger_user_event_t event);
+ */
+typedef enum app_usbd_nrf_dfu_trigger_user_event_e {
+ APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH,
+} app_usbd_nrf_dfu_trigger_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Global definition of app_usbd_nrf_dfu_trigger_t class
+ *
+ * @param instance_name Name of global instance
+ * @param interface_number Unique interface number
+ * @param p_nordic_dfu Pointer to @ref app_usbd_nrf_dfu_trigger_nordic_info_t structure
+ * @param sem_ver_str Semantic version string
+ * @param user_ev_handler User event handler (optional)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF_INTERNAL
+ *
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF)*/
+#define APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ user_ev_handler) \
+ APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ 0, \
+ 0, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ user_ev_handler)
+/*lint -restore*/
+
+/**
+ * @@brief Helper function to get class instance from Nordic DFU Trigger
+ *
+ * @param[in] p_dfu Nordic DFU Trigger instance
+ * (declared by @ref APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF)
+ *
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_nrf_dfu_trigger_class_inst_get(app_usbd_nrf_dfu_trigger_t const * p_dfu)
+{
+ return &p_dfu->base;
+}
+
+/**
+ * @brief Helper function to get DFU from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ *
+ * @return DFU class handle
+ */
+static inline app_usbd_nrf_dfu_trigger_t const *
+app_usbd_nrf_dfu_trigger_class_get( app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_nrf_dfu_trigger_t const *)p_inst;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_NRF_DFU_TRIGGER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h
new file mode 100644
index 0000000..9195e2a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_NRF_DFU_TRIGGER_INTERNAL_H__
+#define APP_USBD_NRF_DFU_TRIGGER_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger_internals USB Nordic DFU Trigger internals
+ * @ingroup app_usbd_nrf_dfu_trigger
+ *
+ * @brief @tagAPI52840 Internals of the USB Nordic DFU Trigger class.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of Nordic DFU Trigger Class type
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_nrf_dfu_trigger);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_nrf_dfu_trigger_user_event_e
+ *
+ */
+enum app_usbd_nrf_dfu_trigger_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event User event
+ *
+ * */
+typedef void (*app_usbd_nrf_dfu_trigger_user_ev_handler_t)(
+ app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_nrf_dfu_trigger_user_event_e event);
+
+/**
+ * @brief Nordic DFU Trigger part of class instance data
+ */
+typedef struct {
+ size_t const sem_ver_size; //!< Semantic string size
+ uint16_t const detach_timeout; //!< Detach timeout in ms - for compatibility with DFU spec.
+ uint16_t const transfer_size; //!< Transfer size - for compatibility with DFU spec.
+ uint16_t const bcd_dfu; //!< DFU spec version.
+ uint8_t const * p_sem_ver; //!< Pointer to semantic version string
+
+ app_usbd_nrf_dfu_trigger_nordic_info_t const * p_dfu_info; //!< Pointer to Nordic DFU Info
+
+ app_usbd_nrf_dfu_trigger_user_ev_handler_t user_ev_handler; //!< User event handler
+} app_usbd_nrf_dfu_trigger_inst_t;
+
+/**
+ * @brief Internal module state
+ *
+ * @note For future compatibility with DFU class.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_STATE_IDLE, /**< Internal module state IDLE */
+ APP_USBD_NRF_DFU_TRIGGER_STATE_DETACH, /**< Internal module state DETACH */
+} app_usbd_nrf_dfu_trigger_state_t;
+
+/**
+ * @brief Nordic DFU Trigger context
+ *
+ * */
+typedef struct {
+ app_usbd_nrf_dfu_trigger_state_t state; //!< Internal module state
+} app_usbd_nrf_dfu_trigger_ctx_t;
+
+
+/**
+ * @brief Nordic DFU Trigger configuration macro
+ *
+ * Used by @ref APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF
+ *
+ * @param iface Interface number
+ * */
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG(iface) (iface)
+
+
+/**
+ * @brief Specific class constant data for Nordic DFU Trigger
+ *
+ * @ref app_usbd_nrf_dfu_trigger_inst_t
+ */
+#define APP_USBD_NRF_DFU_TRIGGER_INSTANCE_SPECIFIC_DEC app_usbd_nrf_dfu_trigger_inst_t inst;
+
+
+/**
+ * @brief Configures Nordic DFU Trigger instance
+ *
+ * @param user_event_handler User event handler
+ * @param p_nordic_dfu Pointer to @ref app_usbd_nrf_dfu_trigger_nordic_info_t structure
+ * @param sem_ver_str Semantic version string
+ * @param timeout Detach timeout in ms - left for compatibility with USB DFU spec.
+ * @param size Transfer size in bytes - left for compatibility with USB DFU spec.
+ * @param bcd USB DFU specification version.
+ */
+#define APP_USBD_NRF_DFU_TRIGGER_INST_CONFIG(user_event_handler, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ timeout, \
+ size, \
+ bcd) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .p_dfu_info = p_nordic_dfu, \
+ .p_sem_ver = sem_ver_str, \
+ .sem_ver_size = sizeof(sem_ver_str), \
+ .transfer_size = size, \
+ .detach_timeout = timeout, \
+ .bcd_dfu = bcd, \
+ }
+
+/**
+ * @brief Specific class data for Nordic DFU Trigger
+ *
+ * @ref app_usbd_nrf_dfu_trigger_ctx_t
+ * */
+#define APP_USBD_NRF_DFU_TRIGGER_DATA_SPECIFIC_DEC app_usbd_nrf_dfu_trigger_ctx_t ctx;
+
+
+/**
+ * @brief Public Nordic DFU Trigger class interface
+ */
+extern const app_usbd_class_methods_t app_usbd_nrf_dfu_trigger_class_methods;
+
+/**
+ * @brief Global definition of Nordic DFU Trigger instance
+ */
+#define APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ detach_timeout, \
+ transfer_size, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ user_ev_handler) \
+ APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_nrf_dfu_trigger, \
+ &app_usbd_nrf_dfu_trigger_class_methods, \
+ APP_USBD_NRF_DFU_TRIGGER_CONFIG((interface_number)), \
+ (APP_USBD_NRF_DFU_TRIGGER_INST_CONFIG(user_ev_handler, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ detach_timeout, \
+ transfer_size, \
+ 0x0110)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_NRF_DFU_TRIGGER_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h
new file mode 100644
index 0000000..93f7fb9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_NRF_DFU_TRIGGER_TYPES_H__
+#define APP_USBD_NRF_DFU_TRIGGER_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger_types USB Nordic DFU Trigger types
+ * @ingroup app_usbd_nrf_dfu_trigger
+ *
+ * @brief @tagAPI52840 Types used in the USB Nordic DFU Trigger class.
+ * @{
+ */
+
+/** @brief Nordic DFU Trigger class definition in interface descriptor
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_NRF_DFU_TRIGGER_CLASS 0xFF
+
+/**
+ * @brief Nordic DFU Trigger subclass possible value
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_SUBCLASS = 0x01, /**< Device Firmware Upgrade Code */
+} app_usbd_nrf_dfu_trigger_subclass_t;
+
+/**
+ * @brief Nordic DFU Trigger protocol possible value
+ *
+ * @note Only Run-time protocol is implemented, as DFU mode is covered by Nordic DFU.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME = 0x01, /**< Run-time Protocol */
+} app_usbd_nrf_dfu_trigger_protocol_t;
+
+/**
+ * @brief Nordic DFU Trigger USB requests @ref nrf_drv_usbd_setup_t::bmRequestType
+ *
+ * @note Requests are limited only to @ref APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME protocol type.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_REQ_DETACH = 0x00, /**< Switch to DFU mode */
+ APP_USBD_NRF_DFU_TRIGGER_REQ_NORDIC_INFO = 0x07, /**< Request Nordic DFU information */
+ APP_USBD_NRF_DFU_TRIGGER_REQ_SEM_VER = 0x08, /**< Request semantic version information */
+} app_usbd_nrf_dfu_trigger_req_t;
+
+/**
+ * @brief Nordic DFU Trigger Functional Descriptor types.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_CS_FUNCTIONAL = 0x21, /**< Functional descriptor type.*/
+} app_usbd_nrf_dfu_trigger_func_type_t;
+
+/**
+ * @brief Nordic DFU Trigger functional descriptor bmAttributes bit masks.
+ *
+ * @note For future compatibility with DFU class.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_BIT_CAN_DNLOAD = 0x01, /**< bitCanDnload */
+ APP_USBD_NRF_DFU_TRIGGER_BIT_CAB_UPLOAD = 0x02, /**< bitCanUpload */
+ APP_USBD_NRF_DFU_TRIGGER_BIT_MANI_TOLERANT = 0x04, /**< bitManifestationTolerant */
+ APP_USBD_NRF_DFU_TRIGGER_BIT_WILL_DETACH = 0x08, /**< bitWillDetach */
+} app_usbd_nrf_dfu_trigger_bm_attributes_t;
+
+#pragma pack(push, 1)
+
+/**
+ * @brief Nordic DFU Trigger Functional Descriptor
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this descriptor in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type.
+ uint8_t bmAttributes; //!< Attributes bits.
+ uint16_t wDetachTimeOut; //!< Device detach timeout - left for compatibility with USB DFU spec.
+ uint16_t wTransferSize; //!< Transfer size - left for compatibility with USB DFU spec.
+ uint16_t bcdDFUVersion; //!< DFU version.
+} app_usbd_nrf_dfu_trigger_desc_func_t;
+
+/**
+ * @brief Nordic custom DFU information.
+ */
+typedef struct {
+ uint32_t wAddress; //!< Firmware start address.
+ uint32_t wFirmwareSize; //!< Firmware size.
+ uint16_t wVersionMajor; //!< Firmware version major.
+ uint16_t wVersionMinor; //!< Firmware version minor.
+ uint32_t wFirmwareID; //!< Firmware ID.
+ uint32_t wFlashSize; //!< Flash size.
+ uint32_t wFlashPageSize; //!< Flash page size.
+} app_usbd_nrf_dfu_trigger_nordic_info_t;
+
+#pragma pack(pop)
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_NRF_DFU_TRIGGER_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h
new file mode 100644
index 0000000..3c9da6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_STRING_CONFIG_H
+#define APP_USBD_STRING_CONFIG_H
+
+/**
+ * @defgroup app_usbd_string_conf USBD string configuration
+ * @ingroup app_usbd_string_desc
+ *
+ * @brief @tagAPI52840 Configuration of the string module that can be easily affected by the final
+ * user.
+ * @{
+ */
+
+/**
+ * @brief Supported languages identifiers
+ *
+ * Comma separated list of supported languages.
+ */
+#define APP_USBD_STRINGS_LANGIDS \
+ ((uint16_t)APP_USBD_LANG_ENGLISH | (uint16_t)APP_USBD_SUBLANG_ENGLISH_US)
+
+/**
+ * @brief Manufacturer name string descriptor
+ *
+ * Comma separated list of manufacturer names for each defined language.
+ * Use @ref APP_USBD_STRING_DESC macro to create string descriptor.
+ *
+ * The order of manufacturer names has to be the same like in
+ * @ref APP_USBD_STRINGS_LANGIDS.
+ */
+#define APP_USBD_STRINGS_MANUFACTURER \
+ APP_USBD_STRING_DESC('N', 'o', 'r', 'd', 'i', 'c', ' ', 'S', 'e', 'm', 'i', 'c', 'o', 'n', 'd', 'u', 'c', 't', 'o', 'r')
+
+/**
+ * @brief Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by @ref APP_USBD_STRING_DESC
+ * or declared as global variable.
+ * */
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+
+/**
+ * @brief Product name string descriptor
+ *
+ * List of product names defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER
+ */
+#define APP_USBD_STRINGS_PRODUCT \
+ APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', ' ', 'U', 'S', 'B', ' ', 'D', 'e', 'm', 'o')
+
+
+/**
+ * @brief Define whether @ref APP_USBD_STRINGS_PRODUCT is created by @ref APP_USBD_STRING_DESC
+ * or declared as global variable.
+ * */
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+
+/**
+ * @brief Serial number string descriptor
+ *
+ * Create serial number string descriptor using @ref APP_USBD_STRING_DESC,
+ * or configure it to point to any internal variable pointer filled with descriptor.
+ *
+ * @note
+ * There is only one SERIAL number inside the library and it is Language independent.
+ */
+#define APP_USBD_STRING_SERIAL \
+ APP_USBD_STRING_DESC('0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0')
+
+/**
+ * @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC
+ * or declared as global variable.
+ * */
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+
+/**
+ * @brief User strings default values
+ *
+ * This value stores all application specific user strings with its default initialization.
+ * The setup is done by X-macros.
+ * Expected macro parameters:
+ * @code
+ * X(mnemonic, [=str_idx], ...)
+ * @endcode
+ * - @c mnemonic: Mnemonic of the string descriptor that would be added to
+ * @ref app_usbd_string_desc_idx_t enumerator.
+ * - @c str_idx : String index value, may be set or left empty.
+ * For example WinUSB driver requires descriptor to be present on 0xEE index.
+ * Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
+ * - @c ... : List of string descriptors for each defined language.
+ */
+#define APP_USBD_STRINGS_USER \
+ X(APP_USER_1, , APP_USBD_STRING_DESC('U', 's', 'e', 'r', ' ', '1'))
+
+/** @} */
+#endif /* APP_USBD_STRING_CONFIG_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c
new file mode 100644
index 0000000..88b38e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+#include "nrf.h"
+#include <stdio.h>
+#include "app_error.h"
+#include "nordic_common.h"
+#include "sdk_errors.h"
+
+/**@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.
+ */
+void app_error_handler_bare(ret_code_t error_code)
+{
+ error_info_t error_info =
+ {
+ .line_num = 0,
+ .p_file_name = NULL,
+ .err_code = error_code,
+ };
+
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+
+void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
+{
+ /* static error variables - in order to prevent removal by optimizers */
+ static volatile struct
+ {
+ uint32_t fault_id;
+ uint32_t pc;
+ uint32_t error_info;
+ assert_info_t * p_assert_info;
+ error_info_t * p_error_info;
+ ret_code_t err_code;
+ uint32_t line_num;
+ const uint8_t * p_file_name;
+ } m_error_data = {0};
+
+ // 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_data.fault_id = id;
+ m_error_data.pc = pc;
+ m_error_data.error_info = info;
+
+ switch (id)
+ {
+ case NRF_FAULT_ID_SDK_ASSERT:
+ m_error_data.p_assert_info = (assert_info_t *)info;
+ m_error_data.line_num = m_error_data.p_assert_info->line_num;
+ m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
+ break;
+
+ case NRF_FAULT_ID_SDK_ERROR:
+ m_error_data.p_error_info = (error_info_t *)info;
+ m_error_data.err_code = m_error_data.p_error_info->err_code;
+ m_error_data.line_num = m_error_data.p_error_info->line_num;
+ m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
+ break;
+ }
+
+ UNUSED_VARIABLE(m_error_data);
+
+ // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
+ __disable_irq();
+ while (loop);
+
+ __enable_irq();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h
new file mode 100644
index 0000000..b831f7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup 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 <stdio.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "nordic_common.h"
+#include "app_error_weak.h"
+#ifdef ANT_STACK_SUPPORT_REQD
+#include "ant_error.h"
+#endif // ANT_STACK_SUPPORT_REQD
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_FAULT_ID_SDK_RANGE_START (0x00004000) /**< The start of the range of error IDs defined in the SDK. */
+
+/**@defgroup APP_ERROR_FAULT_IDS Fault ID types
+ * @{ */
+#define NRF_FAULT_ID_SDK_ERROR (NRF_FAULT_ID_SDK_RANGE_START + 1) /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
+#define NRF_FAULT_ID_SDK_ASSERT (NRF_FAULT_ID_SDK_RANGE_START + 2) /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
+/**@} */
+
+/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
+ */
+typedef struct
+{
+ uint32_t line_num; /**< The line number where the error occurred. */
+ uint8_t const * p_file_name; /**< The file in which the error occurred. */
+ uint32_t err_code; /**< The error code representing the error that occurred. */
+} error_info_t;
+
+/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
+ */
+typedef struct
+{
+ uint16_t line_num; /**< The line number where the error occurred. */
+ uint8_t const * p_file_name; /**< The file in which the error occurred. */
+} assert_info_t;
+
+/**@brief Defines required by app_error_handler assembler intructions.
+ */
+#define APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM (offsetof(error_info_t, line_num))
+#define APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME (offsetof(error_info_t, p_file_name))
+#define APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE (offsetof(error_info_t, err_code))
+#define APP_ERROR_ERROR_INFO_SIZE (sizeof(error_info_t))
+#define APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE \
+ ALIGN_NUM(APP_ERROR_ERROR_INFO_SIZE, sizeof(uint64_t))
+
+
+/**@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 Function for error handling, which is called when an error has occurred.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ */
+void app_error_handler_bare(ret_code_t error_code);
+
+/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. Refer to each fault
+ * identifier for details.
+ */
+void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
+
+/**@brief Function for logging details of error and flushing logs.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. Refer to each fault
+ * identifier for details.
+ */
+void app_error_log_handle(uint32_t id, uint32_t pc, uint32_t info);
+
+
+/**@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_bare((ERR_CODE)); \
+ } 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)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_ERROR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c
new file mode 100644
index 0000000..b2420ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#include "compiler_abstraction.h"
+#include "app_error.h"
+
+#if defined (__CORTEX_M) && (__CORTEX_M == 0x04)
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name) __attribute__(( naked ));
+
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ __ASM volatile(
+
+ "push {lr} \n"
+
+ /* reserve space on stack for error_info_t struct - preserve 8byte stack aligment */
+ "sub sp, sp, %0 \n"
+
+ /* prepare error_info_t struct */
+ "str r0, [sp, %1] \n"
+ "str r1, [sp, %3] \n"
+ "str r2, [sp, %2] \n"
+
+ /* prepare arguments and call function: app_error_fault_handler */
+ "ldr r0, =%4 \n"
+ "mov r1, lr \n"
+ "mov r2, sp \n"
+ "bl %5 \n"
+
+ /* release stack */
+ "add sp, sp, %0 \n"
+
+ "pop {pc} \n"
+ ".ltorg \n"
+
+ : /* Outputs */
+ : /* Inputs */
+ "I" (APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE),
+ "I" (APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE),
+ "I" (APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME),
+ "I" (APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM),
+ "X" (NRF_FAULT_ID_SDK_ERROR),
+ "X" (app_error_fault_handler)
+ : /* Clobbers */
+ "r0", "r1", "r2"
+ );
+}
+#elif defined(__CORTEX_M) && (__CORTEX_M == 0x00)
+/* NRF51 implementation is currently not supporting PC readout */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info = {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+#else
+#error Architecture not supported
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c
new file mode 100644
index 0000000..1a6dc54
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#include "compiler_abstraction.h"
+#include "app_error.h"
+
+#if defined (__CORTEX_M) && (__CORTEX_M == 0x04)
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ __ASM volatile(
+ "push {lr} \n"
+ /* reserve space on stack for error_info_t struct */
+ "sub sp, sp, %0 \n"
+
+ /* prepare error_info_t struct */
+ "str r0, [sp, %1] \n"
+ "str r1, [sp, %3] \n"
+ "str r2, [sp, %2] \n"
+
+ /* prepare arguments and call function: app_error_fault_handler */
+ "ldr.n r0, 1f \n"
+ "mov r1, LR \n"
+ "mov r2, sp \n"
+
+ /* call app_error_fault_handler */
+ "bl %c5 \n"
+
+ /* release stack */
+ "add sp, sp, %0 \n"
+ "pop {pc} \n"
+
+ "DATA \n"
+ "1: \n"
+ " DC32 %c4 \n"
+
+ : /* Outputs */
+ : /* Inputs */
+ "i" (APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE),
+ "i" (APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE),
+ "i" (APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME),
+ "i" (APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM),
+ "i" (NRF_FAULT_ID_SDK_ERROR),
+ "i" (app_error_fault_handler)
+ : /* CLobbers */
+ "r0", "r1", "r2"
+ );
+}
+#elif defined(__CORTEX_M) && (__CORTEX_M == 0x00)
+/* NRF51 implementation is currently not supporting PC readout */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info = {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+#else
+#error Architecture not supported
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c
new file mode 100644
index 0000000..4ce648c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#include "compiler_abstraction.h"
+#include "app_error.h"
+
+#if defined (__CORTEX_M) && (__CORTEX_M == 0x04)
+__ASM void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ PRESERVE8 {TRUE}
+ THUMB
+
+ push {lr}
+
+ /* reserve space on stack for error_info_t struct - preserve 8byte stack aligment */
+ sub sp, sp, #__cpp(APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE)
+
+ /* prepare error_info_t struct */
+ str r0, [sp, #__cpp(APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE)]
+ str r1, [sp, #__cpp(APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM)]
+ str r2, [sp, #__cpp(APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME)]
+
+ /* prepare arguments and call function: app_error_fault_handler */
+ mov r0, #__cpp(NRF_FAULT_ID_SDK_ERROR)
+ mov r1, lr
+ mov r2, sp
+
+ /* call function */
+ bl __cpp(app_error_fault_handler)
+
+ /* release stack */
+ add sp, sp, #__cpp(APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE)
+
+ pop {pc}
+}
+#elif defined(__CORTEX_M) && (__CORTEX_M == 0x00)
+/* NRF51 implementation is currently not supporting PC readout */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info = {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+#else
+#error Architecture not supported
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c
new file mode 100644
index 0000000..0e0130a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "app_error.h"
+
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_strerror.h"
+
+#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+#include "nrf_sdm.h"
+#endif
+
+/*lint -save -e14 */
+/**
+ * Function is implemented as weak so that it can be overwritten by custom application error handler
+ * when needed.
+ */
+__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
+{
+ __disable_irq();
+ NRF_LOG_FINAL_FLUSH();
+
+#ifndef DEBUG
+ NRF_LOG_ERROR("Fatal error");
+#else
+ switch (id)
+ {
+#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+ case NRF_FAULT_ID_SD_ASSERT:
+ NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED");
+ break;
+ case NRF_FAULT_ID_APP_MEMACC:
+ NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS");
+ break;
+#endif
+ case NRF_FAULT_ID_SDK_ASSERT:
+ {
+ assert_info_t * p_info = (assert_info_t *)info;
+ NRF_LOG_ERROR("ASSERTION FAILED at %s:%u",
+ p_info->p_file_name,
+ p_info->line_num);
+ break;
+ }
+ case NRF_FAULT_ID_SDK_ERROR:
+ {
+ error_info_t * p_info = (error_info_t *)info;
+ NRF_LOG_ERROR("ERROR %u [%s] at %s:%u\r\nPC at: 0x%08x",
+ p_info->err_code,
+ nrf_strerror_get(p_info->err_code),
+ p_info->p_file_name,
+ p_info->line_num,
+ pc);
+ NRF_LOG_ERROR("End of error report");
+ break;
+ }
+ default:
+ NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc);
+ break;
+ }
+#endif
+
+ NRF_BREAKPOINT_COND;
+ // On assert, the system can only recover with a reset.
+
+#ifndef DEBUG
+ NRF_LOG_WARNING("System reset");
+ NVIC_SystemReset();
+#else
+ app_error_save_and_stop(id, pc, info);
+#endif // DEBUG
+}
+/*lint -restore */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h
new file mode 100644
index 0000000..fd1a502
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_ERROR_WEAK_H__
+#define APP_ERROR_WEAK_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+/**@brief Callback function for errors, asserts, and faults.
+ *
+ * @details This function is called every time an error is raised in app_error, nrf_assert, or
+ * in the SoftDevice. Information about the error can be found in the @p info
+ * parameter.
+ *
+ * See also @ref nrf_fault_handler_t for more details.
+ *
+ * @note The function is implemented as weak so that it can be redefined by a custom error
+ * handler when needed.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. The value of the @p id
+ * parameter dictates how to interpret this parameter. Refer to the documentation
+ * for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
+ * details about interpreting @p info.
+ */
+void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info);
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_ERROR_WEAK_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h
new file mode 100644
index 0000000..b5adb20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h
@@ -0,0 +1,1204 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup 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 <stddef.h>
+#include "compiler_abstraction.h"
+#include "nordic_common.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @cond (NODOX)
+ */
+/*lint -save -e27 -e10 -e19 */
+#if defined (__LINT__)
+#define STACK_BASE 0x1F000 // Arbitrary value.
+#define STACK_TOP 0x20000 // Arbitrary value.
+
+#elif defined ( __CC_ARM )
+extern char STACK$$Base;
+extern char STACK$$Length;
+#define STACK_BASE &STACK$$Base
+#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length))
+
+#elif defined ( __ICCARM__ )
+extern char CSTACK$$Base;
+extern char CSTACK$$Length;
+#define STACK_BASE &CSTACK$$Base
+#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length))
+
+#elif defined ( __GNUC__ )
+extern uint32_t __StackTop;
+extern uint32_t __StackLimit;
+#define STACK_BASE &__StackLimit
+#define STACK_TOP &__StackTop
+#endif
+
+/* These macros are valid only when absolute placement is used for the application
+ * image. The macros are not compile time symbols. They cannot be used as a
+ * constant expression, for example, inside a static assert or linker script
+ * at-placement. */
+#if defined (__LINT__)
+#define CODE_START (0) // Arbitrary value.
+#define CODE_END (0x1000) // Arbitrary value.
+#define CODE_SIZE (0x1000) // Arbitrary value.
+
+#elif defined ( __CC_ARM )
+extern char Load$$LR$$LR_IROM1$$Base;
+extern char Load$$LR$$LR_IROM1$$Length;
+extern char Load$$LR$$LR_IROM1$$Limit;
+#define CODE_START ((uint32_t)&Load$$LR$$LR_IROM1$$Base)
+#define CODE_END ((uint32_t)&Load$$LR$$LR_IROM1$$Limit)
+#define CODE_SIZE ((uint32_t)&Load$$LR$$LR_IROM1$$Length)
+
+#elif defined ( __ICCARM__ )
+extern void * __vector_table;
+extern char RO_END$$Base;
+#define CODE_START ((uint32_t)&__vector_table)
+#define CODE_END ((uint32_t)&RO_END$$Base)
+#define CODE_SIZE (CODE_END - CODE_START)
+
+#elif defined(__SES_ARM)
+extern uint32_t * _vectors;
+extern uint32_t __FLASH_segment_used_end__;
+#define CODE_START ((uint32_t)&_vectors)
+#define CODE_END ((uint32_t)&__FLASH_segment_used_end__)
+#define CODE_SIZE (CODE_END - CODE_START)
+
+#elif defined ( __GNUC__ )
+extern uint32_t __isr_vector;
+extern uint32_t __etext;
+#define CODE_START ((uint32_t)&__isr_vector)
+#define CODE_END ((uint32_t)&__etext)
+#define CODE_SIZE (CODE_END - CODE_START)
+#endif
+/** @}
+ * @endcond
+ */
+/* lint -restore */
+
+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 Counts number of bits required for the given value
+ *
+ * The macro technically searches for the highest bit set.
+ * For value 0 it returns 0.
+ *
+ * @param val Value to be processed
+ *
+ * @return Number of bits required for the given value
+ */
+//lint -emacro(572,VBITS)
+#define VBITS(val) VBITS_32(val)
+
+/**
+ * @def VBITS_1
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_2
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_4
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_8
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_16
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_32
+ * @brief Internal macro used by @ref VBITS */
+#define VBITS_1( v) ((((v) & (0x0001U << 0)) != 0) ? 1U : 0U)
+#define VBITS_2( v) ((((v) & (0x0001U << 1)) != 0) ? VBITS_1 ((v) >> 1) + 1 : VBITS_1 (v))
+#define VBITS_4( v) ((((v) & (0x0003U << 2)) != 0) ? VBITS_2 ((v) >> 2) + 2 : VBITS_2 (v))
+#define VBITS_8( v) ((((v) & (0x000fU << 4)) != 0) ? VBITS_4 ((v) >> 4) + 4 : VBITS_4 (v))
+#define VBITS_16(v) ((((v) & (0x00ffU << 8)) != 0) ? VBITS_8 ((v) >> 8) + 8 : VBITS_8 (v))
+#define VBITS_32(v) ((((v) & (0xffffU << 16)) != 0) ? VBITS_16((v) >> 16) + 16 : VBITS_16(v))
+
+
+/*Segger embedded studio originally has offsetof macro which cannot be used in macros (like STATIC_ASSERT).
+ This redefinition is to allow using that. */
+#if defined(__SES_ARM) && defined(__GNUC__)
+#undef offsetof
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+/**@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)
+
+
+#ifndef __LINT__
+
+#ifdef __GNUC__
+#define STATIC_ASSERT_SIMPLE(EXPR) _Static_assert(EXPR, "unspecified message")
+#define STATIC_ASSERT_MSG(EXPR, MSG) _Static_assert(EXPR, MSG)
+#endif
+
+#ifdef __CC_ARM
+#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
+#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
+#endif
+
+#ifdef __ICCARM__
+#define STATIC_ASSERT_SIMPLE(EXPR) static_assert(EXPR, "unspecified message")
+#define STATIC_ASSERT_MSG(EXPR, MSG) static_assert(EXPR, MSG)
+#endif
+
+#else // __LINT__
+
+#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_ignore(void))
+#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_ignore(void))
+
+#endif
+
+
+#define _SELECT_ASSERT_FUNC(x, EXPR, MSG, ASSERT_MACRO, ...) ASSERT_MACRO
+
+/**
+ * @brief Static (i.e. compile time) assert macro.
+ *
+ * @note The output of STATIC_ASSERT can be different across compilers.
+ *
+ * Usage:
+ * STATIC_ASSERT(expression);
+ * STATIC_ASSERT(expression, message);
+ *
+ * @hideinitializer
+ */
+//lint -save -esym(???, STATIC_ASSERT)
+#define STATIC_ASSERT(...) \
+ _SELECT_ASSERT_FUNC(x, ##__VA_ARGS__, \
+ STATIC_ASSERT_MSG(__VA_ARGS__), \
+ STATIC_ASSERT_SIMPLE(__VA_ARGS__))
+//lint -restore
+
+
+/**@brief Implementation details for NUM_VAR_ARGS */
+#define NUM_VA_ARGS_IMPL( \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, N, ...) N
+
+
+/**@brief Macro to get the number of arguments in a call variadic macro call
+ *
+ * param[in] ... List of arguments
+ *
+ * @retval Number of variadic arguments in the argument list
+ */
+#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+/**@brief Implementation details for NUM_VAR_ARGS */
+#define NUM_VA_ARGS_LESS_1_IMPL( \
+ _ignored, \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, N, ...) N
+
+/**@brief Macro to get the number of arguments in a call variadic macro call.
+ * First argument is not counted.
+ *
+ * param[in] ... List of arguments
+ *
+ * @retval Number of variadic arguments in the argument list
+ */
+#define NUM_VA_ARGS_LESS_1(...) NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~)
+
+
+/**@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 Macro for performing 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 Macro for checking if an integer 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 Macro for converting 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 Macro for performing 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 Macro 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 Macro for calculating the number of words that are needed to hold a number of bytes.
+ *
+ * @details Adds 3 and divides by 4.
+ *
+ * @param[in] n_bytes The number of bytes.
+ *
+ * @return The number of words that @p n_bytes take up (rounded up).
+ */
+#define BYTES_TO_WORDS(n_bytes) (((n_bytes) + 3) >> 2)
+
+
+/**@brief The number of bytes in a word.
+ */
+#define BYTES_PER_WORD (4)
+
+
+/**@brief Macro for increasing a number to the nearest (larger) multiple of another number.
+ *
+ * @param[in] alignment The number to align to.
+ * @param[in] number The number to align (increase).
+ *
+ * @return The aligned (increased) @p number.
+ */
+#define ALIGN_NUM(alignment, number) (((number) - 1) + (alignment) - (((number) - 1) % (alignment)))
+
+/**@brief Macro for getting first of 2 parameters.
+ *
+ * @param[in] a1 First parameter.
+ * @param[in] a2 Second parameter.
+ */
+#define GET_ARG_1(a1, a2) a1
+
+/**@brief Macro for getting second of 2 parameters.
+ *
+ * @param[in] a1 First parameter.
+ * @param[in] a2 Second parameter.
+ */
+#define GET_ARG_2(a1, a2) a2
+
+
+/**@brief Container of macro (borrowed from Linux kernel).
+ *
+ * This macro returns parent structure address basing on child member address.
+ *
+ * @param ptr Address of child type.
+ * @param type Type of parent structure.
+ * @param member Name of child field in parent structure.
+ *
+ * @return Parent structure address.
+ * */
+#define CONTAINER_OF(ptr, type, member) \
+ (type *)((char *)ptr - offsetof(type, member))
+
+
+/**
+ * @brief Define Bit-field mask
+ *
+ * Macro that defined the mask with selected number of bits set, starting from
+ * provided bit number.
+ *
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ */
+#define BF_MASK(bcnt, boff) ( ((1U << (bcnt)) - 1U) << (boff) )
+
+/**
+ * @brief Get bit-field
+ *
+ * Macro that extracts selected bit-field from provided value
+ *
+ * @param[in] val Value from witch selected bit-field would be extracted
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ *
+ * @return Value of the selected bits
+ */
+#define BF_GET(val, bcnt, boff) ( ( (val) & BF_MASK((bcnt), (boff)) ) >> (boff) )
+
+/**
+ * @brief Create bit-field value
+ *
+ * Value is masked and shifted to match given bit-field
+ *
+ * @param[in] val Value to set on bit-field
+ * @param[in] bcnt Number of bits for bit-field
+ * @param[in] boff Offset of bit-field
+ *
+ * @return Value positioned of given bit-field.
+ */
+#define BF_VAL(val, bcnt, boff) ( (((uint32_t)(val)) << (boff)) & BF_MASK(bcnt, boff) )
+
+/**
+ * @name Configuration of complex bit-field
+ *
+ * @sa BF_CX
+ * @{
+ */
+/** @brief Position of bit count in complex bit-field value */
+#define BF_CX_BCNT_POS 0U
+/** @brief Mask of bit count in complex bit-field value */
+#define BF_CX_BCNT_MASK (0xffU << BF_CX_BCNT_POS)
+/** @brief Position of bit position in complex bit-field value */
+#define BF_CX_BOFF_POS 8U
+/** @brief Mask of bit position in complex bit-field value */
+#define BF_CX_BOFF_MASK (0xffU << BF_CX_BOFF_POS)
+/** @} */
+
+/**
+ * @brief Define complex bit-field
+ *
+ * Complex bit-field would contain its position and size in one number.
+ * @sa BF_CX_MASK
+ * @sa BF_CX_POS
+ * @sa BF_CX_GET
+ *
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ *
+ * @return The single number that describes the bit-field completely.
+ */
+#define BF_CX(bcnt, boff) ( ((((uint32_t)(bcnt)) << BF_CX_BCNT_POS) & BF_CX_BCNT_MASK) | ((((uint32_t)(boff)) << BF_CX_BOFF_POS) & BF_CX_BOFF_MASK) )
+
+/**
+ * @brief Get number of bits in bit-field
+ *
+ * @sa BF_CX
+ *
+ * @param bf_cx Complex bit-field
+ *
+ * @return Number of bits in given bit-field
+ */
+#define BF_CX_BCNT(bf_cx) ( ((bf_cx) & BF_CX_BCNT_MASK) >> BF_CX_BCNT_POS )
+
+/**
+ * @brief Get lowest bit number in the field
+ *
+ * @sa BF_CX
+ *
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Lowest bit number in given bit-field
+ */
+#define BF_CX_BOFF(bf_cx) ( ((bf_cx) & BF_CX_BOFF_MASK) >> BF_CX_BOFF_POS )
+
+/**
+ * @brief Get bit mask of the selected field
+ *
+ * @sa BF_CX
+ *
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Mask of given bit-field
+ */
+#define BF_CX_MASK(bf_cx) BF_MASK(BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Get bit-field
+ *
+ * Macro that extracts selected bit-field from provided value.
+ * Bit-field is given as a complex value.
+ *
+ * @sa BF_CX
+ * @sa BF_GET
+ *
+ * @param[in] val Value from witch selected bit-field would be extracted
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Value of the selected bits.
+ */
+#define BF_CX_GET(val, bf_cx) BF_GET(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Create bit-field value
+ *
+ * Value is masked and shifted to match given bit-field.
+ *
+ * @param[in] val Value to set on bit-field
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Value positioned of given bit-field.
+ */
+#define BF_CX_VAL(val, bf_cx) BF_VAL(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Extracting data from the brackets
+ *
+ * This macro get rid of brackets around the argument.
+ * It can be used to pass multiple arguments in logical one argument to a macro.
+ * Call it with arguments inside brackets:
+ * @code
+ * #define ARGUMENTS (a, b, c)
+ * BRACKET_EXTRACT(ARGUMENTS)
+ * @endcode
+ * It would produce:
+ * @code
+ * a, b, c
+ * @endcode
+ *
+ * @param a Argument with anything inside brackets
+ * @return Anything that appears inside the brackets of the argument
+ *
+ * @note
+ * The argument of the macro have to be inside brackets.
+ * In other case the compilation would fail.
+ */
+#define BRACKET_EXTRACT(a) BRACKET_EXTRACT_(a)
+#define BRACKET_EXTRACT_(a) BRACKET_EXTRACT__ a
+#define BRACKET_EXTRACT__(...) __VA_ARGS__
+
+
+/**
+ * @brief Check if number of parameters is more than 1
+ *
+ * @param ... Arguments to count
+ *
+ * @return 0 If argument count is <= 1
+ * @return 1 If argument count is > 1
+ *
+ * @sa NUM_VA_ARGS
+ * @sa NUM_IS_MORE_THAN_1
+ */
+#define NUM_VA_ARGS_IS_MORE_THAN_1(...) NUM_IS_MORE_THAN_1(NUM_VA_ARGS(__VA_ARGS__))
+
+/**
+ * @brief Check if given numeric value is bigger than 1
+ *
+ * This macro accepts numeric value, that may be the result of argument expansion.
+ * This numeric value is then converted to 0 if it is lover than 1 or to 1 if
+ * its value is higher than 1.
+ * The generated result can be used to glue it into other macro mnemonic name.
+ *
+ * @param N Numeric value to check
+ *
+ * @return 0 If argument is <= 1
+ * @return 1 If argument is > 1
+ *
+ * @note Any existing definition of a form NUM_IS_MORE_THAN_1_PROBE_[N] can
+ * broke the result of this macro
+ */
+#define NUM_IS_MORE_THAN_1(N) NUM_IS_MORE_THAN_1_(N)
+#define NUM_IS_MORE_THAN_1_(N) NUM_IS_MORE_THAN_1_PROBE_(NUM_IS_MORE_THAN_1_PROBE_ ## N, 1)
+#define NUM_IS_MORE_THAN_1_PROBE_(...) GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__))
+#define NUM_IS_MORE_THAN_1_PROBE_0 ~, 0
+#define NUM_IS_MORE_THAN_1_PROBE_1 ~, 0
+
+/**
+ * @brief Get the first argument
+ *
+ * @param ... Arguments to select
+ *
+ * @return First argument or empty if no arguments are provided
+ */
+#define GET_VA_ARG_1(...) GET_VA_ARG_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works
+#define GET_VA_ARG_1_(a1, ...) a1
+
+/**
+ * @brief Get all the arguments but the first one
+ *
+ * @param ... Arguments to select
+ *
+ * @return All arguments after the first one or empty if less than 2 arguments are provided
+ */
+#define GET_ARGS_AFTER_1(...) GET_ARGS_AFTER_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works
+#define GET_ARGS_AFTER_1_(a1, ...) __VA_ARGS__
+
+/**
+ * @brief Size of a field in declared structure
+ *
+ * Macro that returns the size of the structure field.
+ * @param struct_type Variable type to get the field size from
+ * @param field Field name to analyze. It can be even field inside field (field.somethingelse.and_another).
+ *
+ * @return Size of the field
+ */
+#define FIELD_SIZE(struct_type, field) sizeof(((struct struct_type*)NULL)->field)
+
+/**
+ * @brief Number of elements in field array in declared structure
+ *
+ * Macro that returns number of elementy in structure field.
+ * @param struct_type Variable type to get the field size from
+ * @param field Field name to analyze.
+ *
+ * @return Number of elements in field array
+ *
+ * @sa FIELD_SIZE
+ */
+#define FIELD_ARRAY_SIZE(struct_type, field) (FIELD_SIZE(struct_type, field) / FIELD_SIZE(struct_type, field[0]))
+
+/**
+ * @brief Mapping macro
+ *
+ * Macro that process all arguments using given macro
+ *
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP(...) MACRO_MAP_(__VA_ARGS__)
+#define MACRO_MAP_(...) MACRO_MAP_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total
+
+/**
+ * @brief Mapping macro, recursive version
+ *
+ * Can be used in @ref MACRO_MAP macro
+ */
+#define MACRO_MAP_REC(...) MACRO_MAP_REC_(__VA_ARGS__)
+#define MACRO_MAP_REC_(...) MACRO_MAP_REC_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total
+/**
+ * @brief Mapping N arguments macro
+ *
+ * Macro similar to @ref MACRO_MAP but maps exact number of arguments.
+ * If there is more arguments given, the rest would be ignored.
+ *
+ * @param N Number of arguments to map
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument)
+ *
+ * @return Selected number of arguments processed by given macro
+ */
+#define MACRO_MAP_N(N, ...) MACRO_MAP_N_(N, __VA_ARGS__)
+#define MACRO_MAP_N_(N, ...) CONCAT_2(MACRO_MAP_, N)(__VA_ARGS__, )
+
+/**
+ * @brief Mapping N arguments macro, recursive version
+ *
+ * Can be used in @ref MACRO_MAP_N macro
+ */
+#define MACRO_MAP_REC_N(N, ...) MACRO_MAP_REC_N_(N, __VA_ARGS__)
+#define MACRO_MAP_REC_N_(N, ...) CONCAT_2(MACRO_MAP_REC_, N)(__VA_ARGS__, )
+
+#define MACRO_MAP_0( ...)
+#define MACRO_MAP_1( macro, a, ...) macro(a)
+#define MACRO_MAP_2( macro, a, ...) macro(a) MACRO_MAP_1 (macro, __VA_ARGS__, )
+#define MACRO_MAP_3( macro, a, ...) macro(a) MACRO_MAP_2 (macro, __VA_ARGS__, )
+#define MACRO_MAP_4( macro, a, ...) macro(a) MACRO_MAP_3 (macro, __VA_ARGS__, )
+#define MACRO_MAP_5( macro, a, ...) macro(a) MACRO_MAP_4 (macro, __VA_ARGS__, )
+#define MACRO_MAP_6( macro, a, ...) macro(a) MACRO_MAP_5 (macro, __VA_ARGS__, )
+#define MACRO_MAP_7( macro, a, ...) macro(a) MACRO_MAP_6 (macro, __VA_ARGS__, )
+#define MACRO_MAP_8( macro, a, ...) macro(a) MACRO_MAP_7 (macro, __VA_ARGS__, )
+#define MACRO_MAP_9( macro, a, ...) macro(a) MACRO_MAP_8 (macro, __VA_ARGS__, )
+#define MACRO_MAP_10(macro, a, ...) macro(a) MACRO_MAP_9 (macro, __VA_ARGS__, )
+#define MACRO_MAP_11(macro, a, ...) macro(a) MACRO_MAP_10(macro, __VA_ARGS__, )
+#define MACRO_MAP_12(macro, a, ...) macro(a) MACRO_MAP_11(macro, __VA_ARGS__, )
+#define MACRO_MAP_13(macro, a, ...) macro(a) MACRO_MAP_12(macro, __VA_ARGS__, )
+#define MACRO_MAP_14(macro, a, ...) macro(a) MACRO_MAP_13(macro, __VA_ARGS__, )
+#define MACRO_MAP_15(macro, a, ...) macro(a) MACRO_MAP_14(macro, __VA_ARGS__, )
+
+#define MACRO_MAP_REC_0( ...)
+#define MACRO_MAP_REC_1( macro, a, ...) macro(a)
+#define MACRO_MAP_REC_2( macro, a, ...) macro(a) MACRO_MAP_REC_1 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_3( macro, a, ...) macro(a) MACRO_MAP_REC_2 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_4( macro, a, ...) macro(a) MACRO_MAP_REC_3 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_5( macro, a, ...) macro(a) MACRO_MAP_REC_4 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_6( macro, a, ...) macro(a) MACRO_MAP_REC_5 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_7( macro, a, ...) macro(a) MACRO_MAP_REC_6 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_8( macro, a, ...) macro(a) MACRO_MAP_REC_7 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_9( macro, a, ...) macro(a) MACRO_MAP_REC_8 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_10(macro, a, ...) macro(a) MACRO_MAP_REC_9 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_11(macro, a, ...) macro(a) MACRO_MAP_REC_10(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_12(macro, a, ...) macro(a) MACRO_MAP_REC_11(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_13(macro, a, ...) macro(a) MACRO_MAP_REC_12(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_14(macro, a, ...) macro(a) MACRO_MAP_REC_13(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_15(macro, a, ...) macro(a) MACRO_MAP_REC_14(macro, __VA_ARGS__, )
+
+/**
+ * @brief Mapping macro with current index
+ *
+ * Basically macro similar to @ref MACRO_MAP, but the processing function would get an argument
+ * and current argument index (beginning from 0).
+ *
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index)
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR(...) MACRO_MAP_FOR_(__VA_ARGS__)
+#define MACRO_MAP_FOR_N_LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+#define MACRO_MAP_FOR_(...) MACRO_MAP_FOR_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__)
+
+/**
+ * @brief Mapping N arguments macro with current index
+ *
+ * Macro is similar to @ref MACRO_MAP_FOR but maps exact number of arguments.
+ * If there is more arguments given, the rest would be ignored.
+ *
+ * @param N Number of arguments to map
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index)
+ *
+ * @return Selected number of arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_N(N, ...) MACRO_MAP_FOR_N_(N, __VA_ARGS__)
+#define MACRO_MAP_FOR_N_(N, ...) CONCAT_2(MACRO_MAP_FOR_, N)((MACRO_MAP_FOR_N_LIST), __VA_ARGS__, )
+
+#define MACRO_MAP_FOR_0( n_list, ...)
+#define MACRO_MAP_FOR_1( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)))
+#define MACRO_MAP_FOR_2( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_3( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_4( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_5( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_6( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_7( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_8( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_9( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_10(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_11(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_12(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_13(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_14(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_15(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+
+
+/**
+ * @brief Mapping macro with current index and parameter
+ *
+ * Version of @ref MACRO_MAP_FOR that passes also the same parameter to all macros.
+ *
+ * @param param Parameter that would be passed to each macro call during mapping.
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index, param)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_PARAM(param, ...) MACRO_MAP_FOR_PARAM_(param, __VA_ARGS__)
+#define MACRO_MAP_FOR_PARAM_(param, ...) MACRO_MAP_FOR_PARAM_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), param, __VA_ARGS__)
+
+/**
+ * @brief Mapping N arguments macro with with current index and parameter
+ *
+ * @param N Number of arguments to map
+ * @param param Parameter that would be passed to each macro call during mapping.
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index, param)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_PARAM_N(N, param, ...) MACRO_MAP_FOR_PARAM_N_(N, param, __VA_ARGS__)
+#define MACRO_MAP_FOR_PARAM_N_(N, param, ...) CONCAT_2(MACRO_MAP_FOR_PARAM_, N)((MACRO_MAP_FOR_N_LIST), param, __VA_ARGS__, )
+
+
+#define MACRO_MAP_FOR_PARAM_0( n_list, param, ...)
+#define MACRO_MAP_FOR_PARAM_1( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param)
+#define MACRO_MAP_FOR_PARAM_2( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_3( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_4( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_5( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_6( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_7( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_8( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_9( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_10(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_11(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_12(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_13(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_14(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_15(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+
+
+/**
+ * @brief Repeating macro.
+ *
+ * @param count Count of repeats.
+ * @param macro Macro must have the following form: MACRO(arguments).
+ * @param ... Arguments passed to the macro.
+ *
+ * @return All arguments processed by the given macro.
+ */
+#define MACRO_REPEAT(count, macro, ...) MACRO_REPEAT_(count, macro, __VA_ARGS__)
+#define MACRO_REPEAT_(count, macro, ...) CONCAT_2(MACRO_REPEAT_, count)(macro, __VA_ARGS__)
+
+#define MACRO_REPEAT_0(macro, ...)
+#define MACRO_REPEAT_1(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_0(macro, __VA_ARGS__)
+#define MACRO_REPEAT_2(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_1(macro, __VA_ARGS__)
+#define MACRO_REPEAT_3(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_2(macro, __VA_ARGS__)
+#define MACRO_REPEAT_4(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_3(macro, __VA_ARGS__)
+#define MACRO_REPEAT_5(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_4(macro, __VA_ARGS__)
+#define MACRO_REPEAT_6(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_5(macro, __VA_ARGS__)
+#define MACRO_REPEAT_7(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_6(macro, __VA_ARGS__)
+#define MACRO_REPEAT_8(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_7(macro, __VA_ARGS__)
+#define MACRO_REPEAT_9(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_8(macro, __VA_ARGS__)
+#define MACRO_REPEAT_10(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_9(macro, __VA_ARGS__)
+#define MACRO_REPEAT_11(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_10(macro, __VA_ARGS__)
+#define MACRO_REPEAT_12(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_11(macro, __VA_ARGS__)
+#define MACRO_REPEAT_13(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_12(macro, __VA_ARGS__)
+#define MACRO_REPEAT_14(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_13(macro, __VA_ARGS__)
+#define MACRO_REPEAT_15(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_14(macro, __VA_ARGS__)
+
+
+/**
+ * @brief Repeating macro with current index.
+ *
+ * Macro similar to @ref MACRO_REPEAT but the processing function gets the arguments
+ * and the current argument index (beginning from 0).
+
+ * @param count Count of repeats.
+ * @param macro Macro must have the following form: MACRO(index, arguments).
+ * @param ... Arguments passed to the macro.
+ *
+ * @return All arguments processed by the given macro.
+ */
+#define MACRO_REPEAT_FOR(count, macro, ...) MACRO_REPEAT_FOR_(count, macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_(count, macro, ...) CONCAT_2(MACRO_REPEAT_FOR_, count)((MACRO_MAP_FOR_N_LIST), macro, __VA_ARGS__)
+
+#define MACRO_REPEAT_FOR_0(n_list, macro, ...)
+#define MACRO_REPEAT_FOR_1(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_0((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_2(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_1((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_3(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_2((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_4(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_3((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_5(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_4((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_6(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_5((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_7(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_6((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_8(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_7((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_9(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_8((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_10(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_9((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_11(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_12(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_13(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_14(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_15(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+
+/**@brief Adding curly brace to the macro parameter.
+ *
+ * Useful in array of structures initialization.
+ *
+ * @param p Parameter to put into the curly brace. */
+#define PARAM_CBRACE(p) { p },
+
+
+/**@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 encoding a uint40 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 uint40_encode(uint64_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x00000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x0000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0x00FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((value & 0xFF00000000) >> 32);
+ return 5;
+}
+
+/**@brief Function for encoding a uint48 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 uint48_encode(uint64_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x0000000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x00000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x000000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0x0000FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((value & 0x00FF00000000) >> 32);
+ p_encoded_data[5] = (uint8_t) ((value & 0xFF0000000000) >> 40);
+ return 6;
+}
+
+/**@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 uint16 value in big-endian format.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint16_t uint16_big_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint16_t)((uint8_t *)p_encoded_data)[0]) << 8 ) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1])) );
+}
+
+/**@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 decoding a uint32 value in big-endian format.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint32_t uint32_big_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 24) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 0) );
+}
+
+/**
+ * @brief Function for encoding an uint16 value in big-endian format.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data will be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint16_big_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) (value >> 8);
+ p_encoded_data[1] = (uint8_t) (value & 0xFF);
+
+ return sizeof(uint16_t);
+}
+
+/*lint -esym(526, __rev) */
+/*lint -esym(628, __rev) */
+/**@brief Function for encoding a uint32 value in big-endian format.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data will be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ *(uint32_t *)p_encoded_data = __REV(value);
+ return sizeof(uint32_t);
+}
+
+/**@brief Function for decoding a uint40 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value. (uint64_t)
+ */
+static __INLINE uint64_t uint40_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 ));
+}
+
+/**@brief Function for decoding a uint48 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value. (uint64_t)
+ */
+static __INLINE uint64_t uint48_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[5]) << 40 ));
+}
+
+/** @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);
+}
+
+/*lint -e{568, 685} */
+/**
+ * @brief Function for checking if provided address is located in stack space.
+ *
+ * @param[in] ptr Pointer to be checked.
+ *
+ * @return true if address is in stack space, false otherwise.
+ */
+static __INLINE bool is_address_from_stack(void * ptr)
+{
+ if (((uint32_t)ptr >= (uint32_t)STACK_BASE) &&
+ ((uint32_t)ptr < (uint32_t)STACK_TOP) )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h
new file mode 100644
index 0000000..24ae12f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h
@@ -0,0 +1,449 @@
+/**
+ * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_BDS_H__
+#define APP_UTIL_BDS_H__
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+#include "app_util.h"
+#include "ble_srv_common.h"
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8_t nibble_t;
+typedef uint32_t uint24_t;
+typedef uint64_t uint40_t;
+
+/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */
+typedef struct
+{
+ uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */
+ uint8_t list_len; /**< Length of the byte array. */
+} regcertdatalist_t;
+
+/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */
+typedef struct
+{
+ int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */
+ int16_t mantissa; /**< Mantissa, should be using only 12 bits */
+} sfloat_t;
+
+/**@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;
+
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in] p_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 bds_uint16_encode(const uint16_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x00FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0xFF00) >> 8);
+ return sizeof(uint16_t);
+}
+
+static __INLINE uint8_t bds_int16_encode(const int16_t * p_value, uint8_t * p_encoded_data)
+{
+ uint16_t tmp = *p_value;
+ return bds_uint16_encode(&tmp, p_encoded_data);
+}
+
+/**@brief Function for encoding a uint24 value.
+ *
+ * @param[in] p_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 bds_uint24_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
+ return (3);
+}
+
+
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in] p_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 bds_uint32_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((*p_value & 0xFF000000) >> 24);
+ return sizeof(uint32_t);
+}
+
+
+/**@brief Function for encoding a uint40 value.
+ *
+ * @param[in] p_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 bds_uint40_encode(const uint64_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x00000000000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x000000000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x0000000000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((*p_value & 0x00000000FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((*p_value & 0x000000FF00000000) >> 32);
+ return 5;
+}
+
+/**@brief Function for encoding a sfloat value.
+ *
+ * @param[in] p_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 bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_encoded_data)
+{
+ uint16_t encoded_val;
+
+ encoded_val = ((p_value->exponent << 12) & 0xF000) |
+ ((p_value->mantissa << 0) & 0x0FFF);
+
+ return(bds_uint16_encode(&encoded_val, p_encoded_data));
+}
+
+
+/**@brief Function for encoding a uint8_array value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ */
+static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_data, p_value->size);
+ return p_value->size;
+}
+
+
+/**@brief Function for encoding a utf8_str value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+
+ */
+static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_str, p_value->length);
+ return p_value->length;
+}
+
+/**@brief Function for encoding a regcertdatalist value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+
+ */
+static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_list, p_value->list_len);
+ return p_value->list_len;
+}
+
+
+/**@brief Function for decoding a date_time value.
+ *
+ * @param[in] p_date_time pointer to the date_time structure to encode.
+ * @param[in] p_encoded_data pointer to the encoded data
+ * @return length of the encoded field.
+ */
+static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_time,
+ uint8_t * p_encoded_data)
+{
+ uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]);
+
+ 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;
+}
+
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint16_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint16_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 );
+ return (sizeof(uint16_t));
+}
+
+
+/**@brief Function for decoding a int16 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_int16_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ int16_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ uint16_t tmp = 0;
+ uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp);
+ *p_decoded_val = (int16_t)tmp;
+ return retval;
+}
+
+
+/**@brief Function for decoding a uint24 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint24_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint32_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((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);
+ return (3);
+}
+
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint32_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint32_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((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 );
+ return (sizeof(uint32_t));
+}
+
+
+/**@brief Function for decoding a uint40 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint40_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint64_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24 )|
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 );
+ return (40);
+}
+
+
+/**@brief Function for decoding a sfloat value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+
+ */
+static __INLINE uint8_t bds_sfloat_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ sfloat_t * p_decoded_val)
+{
+
+ p_decoded_val->exponent = 0;
+ bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa);
+ p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12);
+ p_decoded_val->mantissa &= 0x0FFF;
+ return len;
+}
+
+
+/**@brief Function for decoding a uint8_array value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint8_array_t * p_decoded_val)
+{
+ memcpy(p_decoded_val->p_data, p_encoded_data, len);
+ p_decoded_val->size = len;
+ return p_decoded_val->size;
+}
+
+
+/**@brief Function for decoding a utf8_str value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ ble_srv_utf8_str_t * p_decoded_val)
+{
+ p_decoded_val->p_str = (uint8_t*)p_encoded_data;
+ p_decoded_val->length = len;
+ return p_decoded_val->length;
+}
+
+
+/**@brief Function for decoding a regcertdatalist value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ regcertdatalist_t * p_decoded_val)
+{
+ memcpy(p_decoded_val->p_list, p_encoded_data, len);
+ p_decoded_val->list_len = len;
+ return p_decoded_val->list_len;
+}
+
+
+/**@brief Function for decoding a date_time value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_date_time pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ ble_date_time_t * p_date_time)
+{
+ UNUSED_VARIABLE(len);
+ uint8_t pos = bds_uint16_decode(len, &p_encoded_data[0], &p_date_time->year);
+ p_date_time->month = p_encoded_data[pos++];
+ p_date_time->day = p_encoded_data[pos++];
+ p_date_time->hours = p_encoded_data[pos++];
+ p_date_time->minutes = p_encoded_data[pos++];
+ p_date_time->seconds = p_encoded_data[pos++];
+
+ return pos;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_BDS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c
new file mode 100644
index 0000000..71690d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "app_util_platform.h"
+
+#ifdef SOFTDEVICE_PRESENT
+/* Global nvic state instance, required by nrf_nvic.h */
+nrf_nvic_state_t nrf_nvic_state;
+#endif
+
+static uint32_t m_in_critical_region = 0;
+
+void app_util_disable_irq(void)
+{
+ __disable_irq();
+ m_in_critical_region++;
+}
+
+void app_util_enable_irq(void)
+{
+ m_in_critical_region--;
+ if (m_in_critical_region == 0)
+ {
+ __enable_irq();
+ }
+}
+
+void app_util_critical_region_enter(uint8_t *p_nested)
+{
+#if __CORTEX_M == (0x04U)
+ ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
+#endif
+
+#if defined(SOFTDEVICE_PRESENT)
+ /* return value can be safely ignored */
+ (void) sd_nvic_critical_region_enter(p_nested);
+#else
+ app_util_disable_irq();
+#endif
+}
+
+void app_util_critical_region_exit(uint8_t nested)
+{
+#if __CORTEX_M == (0x04U)
+ ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
+#endif
+
+#if defined(SOFTDEVICE_PRESENT)
+ /* return value can be safely ignored */
+ (void) sd_nvic_critical_region_exit(nested);
+#else
+ app_util_enable_irq();
+#endif
+}
+
+
+uint8_t privilege_level_get(void)
+{
+#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__)
+ /* the Cortex-M0 has no concept of privilege */
+ return APP_LEVEL_PRIVILEGED;
+#elif __CORTEX_M == (0x04U)
+ uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
+ if (0 == isr_vector_num)
+ {
+ /* Thread Mode, check nPRIV */
+ int32_t control = __get_CONTROL();
+ return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED;
+ }
+ else
+ {
+ /* Handler Mode, always privileged */
+ return APP_LEVEL_PRIVILEGED;
+ }
+#endif
+}
+
+
+uint8_t current_int_priority_get(void)
+{
+ uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_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 APP_IRQ_PRIORITY_THREAD;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h
new file mode 100644
index 0000000..ed478f3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h
@@ -0,0 +1,279 @@
+/**
+ * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup 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 "nrf_nvic.h"
+#endif
+#include "nrf_assert.h"
+#include "app_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __CORTEX_M == (0x00U)
+#define _PRIO_SD_HIGH 0
+#define _PRIO_APP_HIGH 1
+#define _PRIO_APP_MID 1
+#define _PRIO_SD_LOW 2
+#define _PRIO_APP_LOW 3
+#define _PRIO_APP_LOWEST 3
+#define _PRIO_THREAD 4
+#elif __CORTEX_M == (0x04U)
+#define _PRIO_SD_HIGH 0
+#define _PRIO_SD_MID 1
+#define _PRIO_APP_HIGH 2
+#define _PRIO_APP_MID 3
+#define _PRIO_SD_LOW 4
+#define _PRIO_SD_LOWEST 5
+#define _PRIO_APP_LOW 6
+#define _PRIO_APP_LOWEST 7
+#define _PRIO_THREAD 15
+#else
+ #error "No platform defined"
+#endif
+
+
+//lint -save -e113 -e452
+/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
+typedef enum
+{
+#ifndef SOFTDEVICE_PRESENT
+ APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH,
+#else
+ APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH,
+#endif
+ APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH,
+#ifndef SOFTDEVICE_PRESENT
+ APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW,
+#else
+ APP_IRQ_PRIORITY_MID = _PRIO_APP_MID,
+#endif
+ APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW,
+ APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST,
+ APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */
+} app_irq_priority_t;
+//lint -restore
+
+
+/*@brief The privilege levels available to applications in Thread Mode */
+typedef enum
+{
+ APP_LEVEL_UNPRIVILEGED,
+ APP_LEVEL_PRIVILEGED
+} app_level_t;
+
+/**@cond NO_DOXYGEN */
+#define EXTERNAL_INT_VECTOR_OFFSET 16
+/**@endcond */
+
+/**@brief Macro for setting a breakpoint.
+ */
+#if defined(__GNUC__)
+#define NRF_BREAKPOINT __asm__("BKPT 0");
+#else
+#define NRF_BREAKPOINT __BKPT(0)
+#endif
+
+/** @brief Macro for setting a breakpoint.
+ *
+ * If it is possible to detect debugger presence then it is set only in that case.
+ *
+ */
+#if __CORTEX_M == 0x04
+#define NRF_BREAKPOINT_COND do { \
+ /* C_DEBUGEN == 1 -> Debugger Connected */ \
+ if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \
+ { \
+ /* Generate breakpoint if debugger is connected */ \
+ NRF_BREAKPOINT; \
+ } \
+ }while (0)
+#else
+#define NRF_BREAKPOINT_COND NRF_BREAKPOINT
+#endif // __CORTEX_M == 0x04
+
+#if defined ( __CC_ARM )
+#define PACKED(TYPE) __packed TYPE
+#define PACKED_STRUCT PACKED(struct)
+#elif defined ( __GNUC__ )
+#define PACKED __attribute__((packed))
+#define PACKED_STRUCT struct PACKED
+#elif defined (__ICCARM__)
+#define PACKED_STRUCT __packed struct
+#endif
+
+#if defined ( __CC_ARM )
+#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma ("push") \
+ _Pragma ("O3")
+#define PRAGMA_OPTIMIZATION_FORCE_END _Pragma ("pop")
+#elif defined ( __GNUC__ )
+#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma("GCC push_options") \
+ _Pragma ("GCC optimize (\"Os\")")
+#define PRAGMA_OPTIMIZATION_FORCE_END _Pragma ("GCC pop_options")
+#elif defined (__ICCARM__)
+#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma ("optimize=high z")
+#define PRAGMA_OPTIMIZATION_FORCE_END
+#endif
+
+
+void app_util_critical_region_enter (uint8_t *p_nested);
+void app_util_critical_region_exit (uint8_t nested);
+
+/**@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 __CR_NESTED = 0; \
+ app_util_critical_region_enter(&__CR_NESTED);
+#else
+#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL)
+#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() \
+ app_util_critical_region_exit(__CR_NESTED); \
+ }
+#else
+#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0)
+#endif
+
+/* Workaround for Keil 4 */
+#ifndef IPSR_ISR_Msk
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+#endif
+
+
+
+/**@brief Macro to enable anonymous unions from a certain point in the code.
+ */
+#if defined(__CC_ARM)
+ #define ANON_UNIONS_ENABLE _Pragma("push") \
+ _Pragma("anon_unions") \
+ struct semicolon_swallower
+#elif defined(__ICCARM__)
+ #define ANON_UNIONS_ENABLE _Pragma("language=extended") \
+ struct semicolon_swallower
+#else
+ #define ANON_UNIONS_ENABLE struct semicolon_swallower
+ // No action will be taken.
+ // For GCC anonymous unions are enabled by default.
+#endif
+
+/**@brief Macro to disable anonymous unions from a certain point in the code.
+ * @note Call only after first calling @ref ANON_UNIONS_ENABLE.
+ */
+#if defined(__CC_ARM)
+ #define ANON_UNIONS_DISABLE _Pragma("pop") \
+ struct semicolon_swallower
+#elif defined(__ICCARM__)
+ #define ANON_UNIONS_DISABLE struct semicolon_swallower
+ // for IAR leave anonymous unions enabled
+#else
+ #define ANON_UNIONS_DISABLE struct semicolon_swallower
+ // No action will be taken.
+ // For GCC anonymous unions are enabled by default.
+#endif
+
+/**@brief Macro for adding pragma directive only for GCC.
+ */
+#ifdef __GNUC__
+#define GCC_PRAGMA(v) _Pragma(v)
+#else
+#define GCC_PRAGMA(v)
+#endif
+
+/* Workaround for Keil 4 */
+#ifndef CONTROL_nPRIV_Msk
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+#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.
+ */
+uint8_t current_int_priority_get(void);
+
+
+/**@brief Function for finding out the current privilege level.
+ *
+ * @return Current privilege level.
+ * @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level.
+ * @retval APP_LEVEL_PRIVILEGED We are running in privileged level.
+ */
+uint8_t privilege_level_get(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_PLATFORM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h
new file mode 100644
index 0000000..1492acf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2008 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ * @brief Common defines and macros for firmware developed by Nordic Semiconductor.
+ */
+
+#ifndef NORDIC_COMMON_H__
+#define NORDIC_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Check if selected module is enabled
+ *
+ * This is save function for driver enable checking.
+ * Correct from Lint point of view (not using default of undefined value).
+ *
+ * Usage:
+ * @code
+ #if NRF_MODULE_ENABLED(UART)
+ ...
+ #endif
+ * @endcode
+ *
+ * @param module The module name.
+ *
+ * @retval 1 The macro <module>_ENABLE is defined and is non-zero.
+ * @retval 0 The macro <module>_ENABLE is not defined or it equals zero.
+ *
+ * @note
+ * This macro intentionally does not implement second expansion level.
+ * The name of the module to be checked has to be given directly as a parameter.
+ * And given parameter would be connected with @c _ENABLED postfix directly
+ * without evaluating its value.
+ */
+//lint -emacro(491,NRF_MODULE_ENABLED) // Suppers warning 491 "non-standard use of 'defined' preprocessor operator"
+#ifdef NRF_MODULE_ENABLE_ALL
+#warning "Do not use NRF_MODULE_ENABLE_ALL for real builds."
+#define NRF_MODULE_ENABLED(module) 1
+#else
+#define NRF_MODULE_ENABLED(module) \
+ ((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0)
+#endif
+/** The upper 8 bits of a 32 bit value */
+//lint -emacro(572,MSB_32) // Suppress warning 572 "Excessive shift value"
+#define MSB_32(a) (((a) & 0xFF000000) >> 24)
+/** The lower 8 bits (of a 32 bit value) */
+#define LSB_32(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))
+
+/**@brief Concatenates two parameters.
+ *
+ * It realizes two level expansion to make it sure that all the parameters
+ * are actually expanded before gluing them together.
+ *
+ * @param p1 First parameter to concatenating
+ * @param p2 Second parameter to concatenating
+ *
+ * @return Two parameters glued together.
+ * They have to create correct C mnemonic in other case
+ * preprocessor error would be generated.
+ *
+ * @sa CONCAT_3
+ */
+#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2)
+/** Auxiliary macro used by @ref CONCAT_2 */
+#define CONCAT_2_(p1, p2) p1##p2
+
+/**@brief Concatenates three parameters.
+ *
+ * It realizes two level expansion to make it sure that all the parameters
+ * are actually expanded before gluing them together.
+ *
+ * @param p1 First parameter to concatenating
+ * @param p2 Second parameter to concatenating
+ * @param p3 Third parameter to concatenating
+ *
+ * @return Three parameters glued together.
+ * They have to create correct C mnemonic in other case
+ * preprocessor error would be generated.
+ *
+ * @sa CONCAT_2
+ */
+#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3)
+/** Auxiliary macro used by @ref CONCAT_3 */
+#define CONCAT_3_(p1, p2, p3) p1##p2##p3
+
+#define STRINGIFY_(val) #val
+/** Converts a macro argument into a character constant.
+ */
+#define STRINGIFY(val) STRINGIFY_(val)
+
+/** Counts number of elements inside the array
+ */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/**@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)(1U << (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)
+#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NORDIC_COMMON_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c
new file mode 100644
index 0000000..6678e22
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2006 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_assert.h"
+#include "app_error.h"
+#include "nordic_common.h"
+
+__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name)
+{
+ assert_info_t assert_info =
+ {
+ .line_num = line_num,
+ .p_file_name = file_name,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info));
+
+ UNUSED_VARIABLE(assert_info);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h
new file mode 100644
index 0000000..f078910
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2006 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ * @brief Utilities for verifying program logic
+ */
+
+#ifndef NRF_ASSERT_H_
+#define NRF_ASSERT_H_
+
+#include <stdint.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for handling assertions.
+ *
+ *
+ * @note
+ * This function is called when an assertion has triggered.
+ *
+ * @note
+ * This function is deprecated and will be removed in future releases.
+ * Use app_error_fault_handler instead.
+ *
+ *
+ * @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
+ */
+//lint -save -esym(14, assert_nrf_callback)
+void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name);
+//lint -restore
+
+#if (defined(DEBUG_NRF) || defined(DEBUG_NRF_USER))
+#define NRF_ASSERT_PRESENT 1
+#else
+#define NRF_ASSERT_PRESENT 0
+#endif
+
+//#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+
+/*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. */
+
+#ifdef _lint
+#define ASSERT(expr) \
+if (expr) \
+{ \
+} \
+else \
+{ \
+ while (1); \
+}
+#else //_lint
+#define ASSERT(expr) \
+if (NRF_ASSERT_PRESENT) \
+{ \
+ if (expr) \
+ { \
+ } \
+ else \
+ { \
+ assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \
+ } \
+}
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ASSERT_H_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h
new file mode 100644
index 0000000..be2eac5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2006 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BITMASK_H
+#define NRF_BITMASK_H
+
+#include "compiler_abstraction.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8)
+#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007)
+
+/**
+ * Function for checking if bit in the multi-byte bit mask is set.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ *
+ * @return 0 if bit is not set, positive value otherwise.
+ */
+__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask)
+{
+ uint8_t const * p_mask8 = (uint8_t const *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ return (1 << bit) & p_mask8[byte_idx];
+}
+
+/**
+ * Function for setting a bit in the multi-byte bit mask.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ */
+__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask)
+{
+ uint8_t * p_mask8 = (uint8_t *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ p_mask8[byte_idx] |= (1 << bit);
+}
+
+/**
+ * Function for clearing a bit in the multi-byte bit mask.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ */
+__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask)
+{
+ uint8_t * p_mask8 = (uint8_t *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ p_mask8[byte_idx] &= ~(1 << bit);
+}
+
+/**
+ * Function for performing bitwise OR operation on two multi-byte bit masks.
+ *
+ * @param p_mask1 A pointer to the first bit mask.
+ * @param p_mask2 A pointer to the second bit mask.
+ * @param p_mask_out A pointer to the output bit mask.
+ * @param length Length of output mask in bytes.
+ */
+__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1,
+ void const * p_mask2,
+ void * p_out_mask,
+ uint32_t length)
+{
+ uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
+ uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
+ uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ {
+ p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i];
+ }
+}
+
+/**
+ * Function for performing bitwise AND operation on two multi-byte bit masks.
+ *
+ * @param p_mask1 A pointer to the first bit mask.
+ * @param p_mask2 A pointer to the second bit mask.
+ * @param p_mask_out A pointer to the output bit mask.
+ * @param length Length of output mask in bytes.
+ */
+__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1,
+ void const * p_mask2,
+ void * p_out_mask,
+ uint32_t length)
+{
+ uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
+ uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
+ uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ {
+ p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i];
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_BITMASK_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h
new file mode 100644
index 0000000..2266dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file sdk_alloca.h
+ *
+ * @brief Defines alloca() function.
+ *
+ * @details This file defines alloca() function. This can be done directly or by including system
+ * header files. Not all platforms support alloca(). In this case no error will be shown, but
+ * SDK_ALLOCA_DEFINED will be set to 0.
+ */
+
+#ifndef SDK_ALLOCA_H__
+#define SDK_ALLOCA_H__
+
+
+#if defined(__SDK_DOXYGEN__)
+ /** @brief Set to one it alloca() function is available on this platform and it is correctly defined
+ * by this header file.
+ */
+ #define SDK_ALLOCA_DEFINED 1
+#elif defined(__GNUC__)
+ #if defined(__SES_ARM)
+ // SES does not have definition of alloca(), but it have working GCC's __builtin_alloca().
+ #if !defined(alloca)
+ #define alloca(size) __builtin_alloca((size))
+ #endif
+ #else
+ // alloca() can be defined in <malloc.h> on some platforms, but if not then try standard <alloca.h> header file.
+ #include <malloc.h>
+ #if !defined(alloca)
+ #include <alloca.h>
+ #endif
+ #endif
+ #define SDK_ALLOCA_DEFINED 1
+#elif defined(__IAR_SYSTEMS_ICC__)
+ // IAR does not support alloca() function.
+ #define SDK_ALLOCA_DEFINED 0
+#else
+ // All other supported compilers have alloca() definition in <alloca.h> header file.
+ #include <alloca.h>
+ #define SDK_ALLOCA_DEFINED 1
+#endif
+
+
+/*lint -"d__builtin_alloca=(void*)" */
+
+
+#endif // NRF_ALLOCA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h
new file mode 100644
index 0000000..6f65d03
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @cond */
+/**@file
+ *
+ * @ingroup experimental_api
+ * @defgroup sdk_common SDK Common Header
+ * @brief 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 "sdk_config.h"
+#include "nordic_common.h"
+#include "compiler_abstraction.h"
+#include "sdk_os.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @} */
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_COMMON_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h
new file mode 100644
index 0000000..7b5dea5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup 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"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup sdk_err_base Base defined for SDK Modules
+ * @{
+ */
+#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */
+#define NRF_ERROR_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 NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100) /**< Base address for Memory Manager related errors. */
+#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200) /**< Base address for Peripheral drivers related errors. */
+#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300) /**< Base address for Gazelle related errors. */
+#define NRF_ERROR_BLE_IPSP_ERR_BASE (0x8400) /**< Base address for BLE IPSP related errors. */
+#define NRF_ERROR_CRYPTO_ERR_BASE (0x8500) /**< Base address for crypto related errors. */
+/** @} */
+
+
+/**
+ * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors.
+ * @{
+ */
+#define NRF_ERROR_IOT_ERR_BASE_START (0xA000)
+#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF)
+/** @} */
+
+
+/**
+ * @defgroup sdk_common_errors Codes reserved as identification for common errors.
+ * @{
+ */
+#define NRF_ERROR_MODULE_NOT_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000) ///< Module not initialized
+#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001) ///< Mutex initialization failed
+#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002) ///< Mutex lock failed
+#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003) ///< Mutex unlock failed
+#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004) ///< Mutex conditional initialization failed
+#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005) ///< Module already initialized
+#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006) ///< Storage full
+#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010) ///< API not implemented
+#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011) ///< Feature not enabled
+#define NRF_ERROR_IO_PENDING (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0012) ///< Input/Output pending
+/** @} */
+
+
+/**
+ * @defgroup drv_specific_errors Error / status codes specific to drivers.
+ * @{
+ */
+#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000)
+#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001)
+#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002)
+/** @} */
+
+
+/**
+ * @defgroup ble_ipsp_errors IPSP codes
+ * @brief Error and status codes specific to IPSP.
+ * @{
+ */
+#define NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0000)
+#define NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0001)
+#define NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0002)
+#define NRF_ERROR_BLE_IPSP_PEER_REJECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0003)
+/* @} */
+
+
+/**
+ * @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;
+
+/** @} */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_ERRORS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h
new file mode 100644
index 0000000..c33c66e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+
+ * @defgroup sdk_common_macros SDK Common Header
+ * @ingroup app_common
+ * @brief Macros for parameter checking and similar tasks
+ * @{
+ */
+
+#ifndef SDK_MACROS_H__
+#define SDK_MACROS_H__
+
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Macro for parameter checking.
+ *
+ * If @p _cond evaluates to true, does nothing. Otherwise,
+ * if @p _module ## _PARAM_CHECK_DISABLED is @e not set (default), prints an error message
+ * if @p _printfn is provided, and returns from the calling function context with code @p _err.
+ * If @p _module ## _PARAM_CHECK_DISABLED is set, behaves like the ASSERT macro.
+ *
+ * Parameter checking implemented using this macro can be optionally turned off for release code.
+ * Only disable runtime parameter checks if size if a major concern.
+ *
+ * @param _module The module name.
+ * @param _cond The condition to be evaluated.
+ * @param _err The error to be returned.
+ * @param _printfn A printf-compatible function used to log the error.
+ * Leave empty if no logging is needed.
+ *
+ * @hideinitializer
+ */
+/*lint -esym(666, NRF_PARAM_CHECK*) : Expression with side effects passed to macro */
+#define NRF_PARAM_CHECK(_module, _cond, _err, _printfn) \
+ do \
+ { \
+ if ((_cond)) \
+ { \
+ /* Do nothing. */ \
+ } \
+ else if (!(_module ## _PARAM_CHECK_DISABLED)) \
+ { \
+ _printfn("%s check failed in %s() with value 0x%x.", #_cond, __func__, _err); \
+ return (_err); \
+ } \
+ else \
+ { \
+ ASSERT((_cond)); \
+ } \
+ } while (0);
+
+
+/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
+ * err_code if the statement is not true.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is false.
+ */
+#define VERIFY_TRUE(statement, err_code) \
+do \
+{ \
+ if (!(statement)) \
+ { \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
+ * if the statement is not true.
+ *
+ * @param[in] statement Statement to test.
+ */
+#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), )
+
+
+/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
+ * err_code if the statement is not false.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is true.
+ */
+#define VERIFY_FALSE(statement, err_code) \
+do \
+{ \
+ if ((statement)) \
+ { \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
+ * if the statement is not false.
+ *
+ * @param[in] statement Statement to test.
+ */
+#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), )
+
+
+/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
+ * function to return error code of statement if it is not @ref NRF_SUCCESS.
+ *
+ * @param[in] statement Statement to check against NRF_SUCCESS.
+ */
+#define VERIFY_SUCCESS(statement) \
+do \
+{ \
+ uint32_t _err_code = (uint32_t) (statement); \
+ if (_err_code != NRF_SUCCESS) \
+ { \
+ return _err_code; \
+ } \
+} while(0)
+
+
+/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
+ * function to return if the err_code is not @ref NRF_SUCCESS.
+ *
+ * @param[in] err_code The error code to check.
+ */
+#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return @ref NRF_ERROR_INVALID_STATE if not.
+ *
+ * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
+ * should be true if the module is initialized, false if not.
+ */
+#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
+ * should be true if the module is initialized, false if not.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED))
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @param[in] param The variable to check if is NULL.
+ */
+#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @param[in] param The variable to check if is NULL.
+ */
+#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL))
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_MACROS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c
new file mode 100644
index 0000000..df5c09a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_mapped_flags.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "compiler_abstraction.h"
+
+
+// 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 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 (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ for (uint32_t 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_w_idx(uint16_t * p_keys,
+ sdk_mapped_flags_t flags,
+ uint16_t key,
+ uint8_t * p_index)
+{
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ if (p_index != NULL)
+ {
+ *p_index = i;
+ }
+ return sdk_mapped_flags_get_by_index(flags, i);
+ }
+ }
+ }
+ if (p_index != NULL)
+ {
+ *p_index = SDK_MAPPED_FLAGS_N_KEYS;
+ }
+ return false;
+}
+
+
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key)
+{
+ if (p_keys != NULL)
+ {
+ for (uint32_t 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 (uint32_t 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 (uint32_t 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;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h
new file mode 100644
index 0000000..2432c88
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SDK_MAPPED_FLAGS_H__
+#define SDK_MAPPED_FLAGS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "compiler_abstraction.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @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 32 /**< 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 uint32_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. */
+
+
+/**@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 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 from which to read.
+ * @param[in] key The key for which to get the flag.
+ * @param[out] p_index If not NULL, the index of the key.
+ *
+ * @return The state of the flag.
+ */
+bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
+ sdk_mapped_flags_t flags,
+ uint16_t key,
+ uint8_t * p_index);
+
+
+/**@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);
+}
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDK_MAPPED_FLAGS_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h
new file mode 100644
index 0000000..6aeb3d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2013 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @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__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_OS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h
new file mode 100644
index 0000000..eaef717
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ * @brief Definition file for resource usage by SoftDevice, ESB and Gazell.
+ */
+
+#ifndef SDK_RESOURCES_H__
+#define SDK_RESOURCES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(SOFTDEVICE_PRESENT) || defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
+ #include "nrf_sd_def.h"
+#else
+ #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */
+ #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */
+ #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */
+ #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */
+ #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */
+#endif
+
+#ifdef GAZELL_PRESENT
+ #include "nrf_gzll_resources.h"
+#else
+ #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */
+ #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */
+ #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */
+#endif
+
+#ifdef ESB_PRESENT
+ #include "nrf_esb_resources.h"
+#else
+ #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */
+ #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */
+ #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */
+#endif
+
+#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED)
+#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED)
+#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED)
+#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_RESOURCES_H__