aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c358
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h317
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h359
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h180
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c225
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h297
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c474
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h119
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c154
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c255
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h309
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c401
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h491
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h823
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c320
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h512
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h365
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h130
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c305
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h154
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c474
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c1002
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h1238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h232
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h140
38 files changed, 11599 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c
new file mode 100644
index 0000000..6b30f11
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c
@@ -0,0 +1,358 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 "adns2080.h"
+#include "sdio.h"
+
+/*lint ++flb "Enter library region" */
+
+#define ADNS2080_PRODUCT_ID (0x2AU) /*!< ADNS2080 product id */
+#define ADNS2080_RESET_NUMBER (0x5AU) /*!< ADNS2080 reset code */
+
+/* ADNS2080 register addresses */
+#define REG_PROD_ID (0x00U) /*!< Product ID. Default value : 0x2A */
+#define REG_REV_ID (0x01U) /*!< Revision ID. Default value : 0x00 */
+#define REG_MOTION_ST (0x02U) /*!< Motion Status. Default value : 0x00 */
+#define REG_DELTA_X (0x03U) /*!< Lower byte of Delta_X. Default value : 0x00 */
+#define REG_DELTA_Y (0x04U) /*!< Lower byte of Delta_Y. Default value : 0x00 */
+#define REG_SQUAL (0x05U) /*!< Squal Quality. Default value : 0x00 */
+#define REG_SHUT_HI (0x06U) /*!< Shutter Open Time (Upper 8-bit). Default value : 0x00 */
+#define REG_SHUT_LO (0x07U) /*!< Shutter Open Time (Lower 8-bit). Default value : 0x64 */
+#define REG_PIX_MAX (0x08U) /*!< Maximum Pixel Value. Default value : 0xD0 */
+#define REG_PIX_ACCUM (0x09U) /*!< Average Pixel Value. Default value : 0x80 */
+#define REG_PIX_MIN (0x0AU) /*!< Minimum Pixel Value. Default value : 0x00 */
+#define REG_PIX_GRAB (0x0BU) /*!< Pixel Grabber. Default value : 0x00 */
+#define REG_DELTA_XY_HIGH (0x0CU) /*!< Upper 4 bits of Delta X and Y displacement. Default value : 0x00 */
+#define REG_MOUSE_CTRL (0x0DU) /*!< Mouse Control. Default value : 0x01 */
+#define REG_RUN_DOWNSHIFT (0x0EU) /*!< Run to Rest1 Time. Default value : 0x08 */
+#define REG_REST1_PERIOD (0x0FU) /*!< Rest1 Period. Default value : 0x01 */
+#define REG_REST1_DOWNSHIFT (0x10U) /*!< Rest1 to Rest2 Time. Default value : 0x1f */
+#define REG_REST2_PERIOD (0x11U) /*!< Rest2 Period. Default value : 0x09 */
+#define REG_REST2_DOWNSHIFT (0x12U) /*!< Rest2 to Rest3 Time. Default value : 0x2f */
+#define REG_REST3_PERIOD (0x13U) /*!< Rest3 Period. Default value : 0x31 */
+#define REG_PERFORMANCE (0x22U) /*!< Performance. Default value : 0x00 */
+#define REG_RESET (0x3aU) /*!< Reset. Default value : 0x00 */
+#define REG_NOT_REV_ID (0x3fU) /*!< Inverted Revision ID. Default value : 0xff */
+#define REG_LED_CTRL (0x40U) /*!< LED Control. Default value : 0x00 */
+#define REG_MOTION_CTRL (0x41U) /*!< Motion Control. Default value : 0x40 */
+#define REG_BURST_READ_FIRST (0x42U) /*!< Burst Read Starting Register. Default value : 0x03 */
+#define REG_BURST_READ_LAST (0x44U) /*!< Burst Read Ending Register. Default value : 0x09 */
+#define REG_REST_MODE_CONFIG (0x45U) /*!< Rest Mode Confi guration. Default value : 0x00 */
+#define REG_MOTION_BURST (0x63U) /*!< Burst Read. Default value : 0x00 */
+
+/* ADNS2080 register bits */
+#define REG_MOUSE_CTRL_POWERDOWN (0x02U) /*!< Mouse control register powerdown bit */
+#define REG_MOTION_CTRL_MOT_A (0x80U) /*!< Motion control register polarity bit */
+#define REG_MOTION_CTRL_MOT_S (0x40U) /*!< Motion control register edge sensitivity bit */
+#define REG_MOUSE_CTRL_RES_EN (0x40U) /*!< Mouse control register resolution enable bit */
+#define REG_MOUSE_CTRL_BIT_REPORTING (0x80U) /*!< Mouse control register "number of motion bits" bit*/
+
+void adns2080_movement_read(int16_t * deltaX, int16_t * deltaY)
+{
+ uint8_t delta_x; /*!< Stores REG_DELTA_X contents */
+ uint8_t delta_y; /*!< Stores REG_DELTA_Y contents */
+ uint8_t delta_xy_high; /*!< Stores REG_DELTA_XY contents which contains upper 4 bits for both delta_x and delta_y when 12 bit mode is used */
+ uint8_t delta_x_high; /*!< Stores delta_x 4 MSB bits */
+ uint8_t delta_y_high; /*!< Stores delta_y 4 MSB bits */
+
+ uint16_t u16_deltaX; /*!< This is used to buffer the result and will be cast later to int16_t */
+ uint16_t u16_deltaY; /*!< This is used to buffer the result and will be cast later to int16_t */
+
+ delta_x = sdio_read_byte(REG_DELTA_X);
+ delta_y = sdio_read_byte(REG_DELTA_Y);
+
+ if (adns2080_motion_bits_read() == ADNS2080_MOTION_BITS_12)
+ {
+ // In 12 bit mode the upper 4 bits are stored in a separate register
+ // where first 4 upper bits are for delta_x and lower 4 bits for delta_y.
+ delta_xy_high = sdio_read_byte(REG_DELTA_XY_HIGH);
+
+ delta_x_high = ((delta_xy_high & 0xF0) >> 4);
+ delta_y_high = (delta_xy_high & 0x0F);
+
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_x_high & 0x08)
+ {
+ u16_deltaX = 0xF000;
+ }
+ else
+ {
+ u16_deltaX = 0x0000;
+ }
+
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_y_high & 0x08)
+ {
+ u16_deltaY = 0xF000;
+ }
+ else
+ {
+ u16_deltaY = 0x0000;
+ }
+
+ u16_deltaX |= (delta_x_high << 4) | delta_x;
+ u16_deltaY |= (delta_y_high << 4) | delta_y;
+ }
+ else // Only 8 bits is used for motion data
+ {
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_x & 0x80)
+ {
+ u16_deltaX = 0xFF00;
+ }
+ else
+ {
+ u16_deltaX = 0x0000;
+ }
+
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_y & 0x80)
+ {
+ u16_deltaY = 0xFF00;
+ }
+ else
+ {
+ u16_deltaY = 0x0000;
+ }
+
+ u16_deltaX |= delta_x;
+ u16_deltaY |= delta_y;
+ }
+
+ *deltaX = (int16_t)u16_deltaX;
+ *deltaY = (int16_t)u16_deltaY;
+}
+
+adns2080_motion_bits_t adns2080_motion_bits_read(void)
+{
+ /* Read the most significant bit */
+ return (adns2080_motion_bits_t)((sdio_read_byte(REG_MOUSE_CTRL) >> 7) & 0x01);
+}
+
+bool adns2080_is_motion_detected(void)
+{
+ return ((sdio_read_byte(REG_MOTION_ST) & 0x80) != 0);
+}
+
+uint8_t adns2080_product_id_read(void)
+{
+ return sdio_read_byte(REG_PROD_ID);
+}
+
+uint8_t adns2080_revision_id_read(void)
+{
+ return sdio_read_byte(REG_REV_ID);
+}
+
+adns2080_status_t adns2080_init(void)
+{
+ sdio_init();
+ adns2080_reset();
+
+ if (adns2080_product_id_read() != ADNS2080_PRODUCT_ID)
+ {
+ return ADNS2080_CHIP_NOT_DETECTED;
+ }
+
+ sdio_write_byte(REG_BURST_READ_FIRST, REG_DELTA_X);
+ sdio_write_byte(REG_BURST_READ_LAST, REG_DELTA_Y);
+
+ return ADNS2080_OK;
+}
+
+void adns2080_reset(void)
+{
+ sdio_write_byte(REG_RESET, ADNS2080_RESET_NUMBER);
+}
+
+void adns2080_powerdown(void)
+{
+ sdio_write_byte(REG_MOUSE_CTRL, REG_MOUSE_CTRL_POWERDOWN);
+}
+
+void adns2080_wakeup(void)
+{
+ adns2080_reset();
+}
+
+adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity)
+{
+ uint8_t databyte = 0;
+ adns2080_status_t status = ADNS2080_OK;
+
+ switch (polarity)
+ {
+ case ADNS2080_MOTION_OUTPUT_POLARITY_LOW:
+ databyte = 0; // Clear REG_MOTION_CTRL_MOT_A bit
+ break;
+
+ case ADNS2080_MOTION_OUTPUT_POLARITY_HIGH:
+ databyte = REG_MOTION_CTRL_MOT_A;
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ switch (sensitivity)
+ {
+ case ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL:
+ databyte &= ~(REG_MOTION_CTRL_MOT_S);
+ break;
+
+ case ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE:
+ databyte |= (REG_MOTION_CTRL_MOT_S);
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ if (status == ADNS2080_OK)
+ {
+ sdio_write_byte(REG_MOTION_CTRL, databyte);
+ }
+
+ return status;
+}
+
+adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution)
+{
+ uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL);
+ adns2080_status_t status = ADNS2080_OK;
+
+ // Enable resolution settings on REG_MOUSE_CTRL [4:2]
+ databyte |= (REG_MOUSE_CTRL_RES_EN);
+
+ switch (resolution)
+ {
+ case ADNS2080_RESOLUTION_250DPI:
+ case ADNS2080_RESOLUTION_500DPI:
+ case ADNS2080_RESOLUTION_1000DPI:
+ case ADNS2080_RESOLUTION_1250DPI:
+ case ADNS2080_RESOLUTION_1500DPI:
+ case ADNS2080_RESOLUTION_1750DPI:
+ case ADNS2080_RESOLUTION_2000DPI:
+ // Clear resolution bits [4:2]
+ databyte &= ~(0x1C); // 0b00011100;
+ // Set resolution bits
+ databyte |= (uint8_t)((uint8_t)resolution << 2);
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ if (status == ADNS2080_OK)
+ {
+ sdio_write_byte(REG_MOUSE_CTRL, databyte);
+ }
+
+ return status;
+}
+
+adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits)
+{
+ uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL);
+ adns2080_status_t status = ADNS2080_OK;
+
+ switch (motion_bits)
+ {
+ case ADNS2080_MOTION_BITS_8:
+ databyte &= ~(REG_MOUSE_CTRL_BIT_REPORTING);
+ break;
+
+ case ADNS2080_MOTION_BITS_12:
+ databyte |= (REG_MOUSE_CTRL_BIT_REPORTING);
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ if (status == ADNS2080_OK)
+ {
+ sdio_write_byte(REG_MOUSE_CTRL, databyte);
+ }
+
+ return status;
+}
+
+void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period)
+{
+ adns2080_mode_t current_mode = adns2080_force_mode_read();
+ adns2080_force_mode_set(ADNS2080_MODE_RUN1);
+ sdio_write_byte(REG_REST1_PERIOD, rest1_period);
+ sdio_write_byte(REG_REST2_PERIOD, rest2_period);
+ sdio_write_byte(REG_REST3_PERIOD, rest3_period);
+ adns2080_force_mode_set(current_mode);
+}
+
+void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time)
+{
+ adns2080_mode_t current_mode = adns2080_force_mode_read();
+ adns2080_force_mode_set(ADNS2080_MODE_RUN1);
+ sdio_write_byte(REG_RUN_DOWNSHIFT, run_to_rest1_mode_time);
+ sdio_write_byte(REG_REST1_DOWNSHIFT, rest1_to_rest2_mode_time);
+ sdio_write_byte(REG_REST2_DOWNSHIFT, rest2_to_rest3_mode_time);
+ adns2080_force_mode_set(current_mode);
+}
+
+adns2080_mode_t adns2080_force_mode_read(void)
+{
+ return (adns2080_mode_t)((sdio_read_byte(REG_PERFORMANCE) >> 4) & 0x07);
+}
+
+void adns2080_force_mode_set(adns2080_mode_t mode)
+{
+ sdio_write_byte(REG_PERFORMANCE, (uint8_t)((uint8_t)mode << 4));
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h
new file mode 100644
index 0000000..1ea60b6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h
@@ -0,0 +1,317 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef ADNS2080_H
+#define ADNS2080_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief ADNS2080 mouse sensor driver
+*
+* @defgroup nrf_drivers_adns2080 ADNS2080 driver
+* @{
+* @ingroup ext_drivers
+* @brief ADNS2080 mouse sensor driver.
+*/
+
+/**
+ * Describes return values for @ref adns2080_init.
+ */
+typedef enum
+{
+ ADNS2080_OK, /*!< Operation was succesful */
+ ADNS2080_SERIAL_COMM_FAILURE, /*!< Serial communication failed */
+ ADNS2080_CHIP_NOT_DETECTED, /*!< Product/Revision ID was not what was expected */
+ ADNS2080_INVALID_PARAMETER /*!< Given parameters were not valid */
+} adns2080_status_t;
+
+/**
+ * ADNS2080 motion output pin polarity values.
+ */
+typedef enum
+{
+ ADNS2080_MOTION_OUTPUT_POLARITY_LOW = 0, /*!< Motion output polarity active low */
+ ADNS2080_MOTION_OUTPUT_POLARITY_HIGH = 1 /*!< Motion output polarity active high */
+} motion_output_polarity_t;
+
+/**
+ * Motion output pin configuration.
+ */
+typedef enum
+{
+ ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL = 0, /*!< Motion output pin will be driven low/high (depending on the polarity setting) as long as there is motion data in DELTA registers */
+ ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE = 1 /*!< Motion output pin will be driven low/high (depending on the polarity setting) for 380 ns when motion is detected during rest modes */
+} motion_output_sensitivity_t;
+
+/**
+ * Mouse sensor resolution values.
+ */
+typedef enum
+{
+ ADNS2080_RESOLUTION_250DPI = 1, /*!< 250 dpi resolution */
+ ADNS2080_RESOLUTION_500DPI = 2, /*!< 500 dpi resolution */
+ ADNS2080_RESOLUTION_1000DPI = 0, /*!< 1000 dpi resolution */
+ ADNS2080_RESOLUTION_1250DPI = 3, /*!< 1250 dpi resolution */
+ ADNS2080_RESOLUTION_1500DPI = 4, /*!< 1500 dpi resolution */
+ ADNS2080_RESOLUTION_1750DPI = 5, /*!< 1750 dpi resolution */
+ ADNS2080_RESOLUTION_2000DPI = 6 /*!< 2000 dpi resolution */
+} adns2080_resolution_t;
+
+/**
+ * Mouse sensor forced mode options.
+ */
+typedef enum
+{
+ ADNS2080_MODE_NORMAL = 0, /*!< Normal operation mode */
+ ADNS2080_MODE_REST1 = 1, /*!< Rest1 operation mode */
+ ADNS2080_MODE_REST2 = 2, /*!< Rest2 operation mode */
+ ADNS2080_MODE_REST3 = 3, /*!< Rest3 operation mode */
+ ADNS2080_MODE_RUN1 = 4, /*!< Run1 operation mode */
+ ADNS2080_MODE_RUN2 = 5, /*!< Run2 operation mode */
+ ADNS2080_MODE_IDLE = 6 /*!< Idle operation mode */
+} adns2080_mode_t;
+
+/**
+ * Mouse sensor motion reporting bits.
+ */
+typedef enum
+{
+ ADNS2080_MOTION_BITS_8 = 0, /*!< Motion reporting uses 8 bits */
+ ADNS2080_MOTION_BITS_12 = 1 /*!< Motion reporting uses 12 bits */
+} adns2080_motion_bits_t;
+
+/**
+ * @brief Function for initializing the mouse sensor chip.
+ *
+ * Valid mouse sensor information will be available 50 milliseconds after this
+ * function finishes.
+ *
+ * @return
+ * @retval ADNS2080_OK Mouse sensor was initialized succesfully.
+ * @retval ADNS2080_SERIAL_COMM_FAILURE Serial communications failure.
+ * @retval ADNS2080_CHIP_NOT_DETECTED Could not find revision 0 ADNS2080 chip.
+ */
+adns2080_status_t adns2080_init(void);
+
+/**
+ * @brief Function for resetting the mouse sensor chip.
+ *
+ * Valid mouse sensor information will be available 50 milliseconds after this
+ * function finishes.
+ * All register settings will be lost and need to be reloaded.
+ *
+ */
+void adns2080_reset(void);
+
+/**
+ * @brief Function for reading mouse sensor product ID.
+ *
+ * Chip is expected to be initialized before calling this function.
+ * Returned product ID should always be 0x2A.
+ *
+ * @return Product ID.
+ */
+uint8_t adns2080_product_id_read(void);
+
+/**
+ * @brief Function for reading mouse sensor revision ID.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return Product ID.
+ */
+uint8_t adns2080_revision_id_read(void); // also note there is "not rev id" register
+
+/**
+ * @brief Function for powering down the mouse sensor.
+ *
+ * Chip is expected to be initialized before calling this function.
+ * Serial port should not be accessed during the power down. To exit the power
+ * down mode, @ref adns2080_wakeup must be called.
+ *
+ */
+void adns2080_powerdown(void);
+
+/**
+ * @brief Function for waking up the mouse sensor.
+ *
+ * After wakeup, all mouse sensor settings must be reloaded. Valid mouse sensor
+ * information will be available 55 milliseconds after this function finishes.
+ */
+void adns2080_wakeup(void);
+
+/**
+ * @brief Function for configuring the MOTION interrupt output pin.
+ *
+ * When motion is detected by the mouse sensor, the chip has a MOTION pin
+ * indicating there is motion data in DELTA_X and DELTA_Y registers. This
+ * function configures the polarity and sensitivity of that pin.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param polarity MOTION output pin is either active LOW (default) or active HIGH
+ * @param sensitivity Level or Edge (default) sensitive
+ * @return
+ * @retval ADNS2080_OK Operation succeeded.
+ * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range.
+ */
+adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity);
+
+/**
+ * @brief Function for setting mouse sensor resolution.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param resolution Desired resolution.
+ * @return
+ * @retval ADNS2080_OK Operation succeeded.
+ * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range.
+ */
+adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution);
+
+/**
+ * @brief Function for setting number of bits used for mouse sensor motion reporting.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param motion_bits Desired number of bits.
+ * @return
+ * @retval ADNS2080_OK Operation succeeded.
+ * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range.
+ */
+adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits);
+
+/**
+ * @brief Function for reading number of bits used for mouse sensor motion reporting.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return motion_bits Number of bits.
+ */
+adns2080_motion_bits_t adns2080_motion_bits_read(void);
+
+/**
+ * @brief Function for reading X- and Y-axis movement (in counts) since last report.
+ *
+ * Absolute value is determined by resolution.
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param p_delta_x Location to store X-axis movement
+ * @param p_delta_y Location to store Y-axis movement
+ */
+void adns2080_movement_read(int16_t *p_delta_x, int16_t *p_delta_y);
+
+/**
+ * @brief Function for checking if motion has been detected since last call.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return
+ * @retval true, if movement has been detected
+ * @retval false, if no movement has been detected
+ */
+bool adns2080_is_motion_detected(void);
+
+/**
+ * @brief Function for setting mouse sensor Rest1, Rest2 and Rest3 mode motion detection time period.
+ *
+ * Allowed range for the periods is 0x01 to 0xFD.
+ * Resulting period is derived from the following equation :
+ * Period = (Rest period + 1) * 10 milliseconds
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param rest1_period Rest1 period
+ * @param rest2_period Rest2 period
+ * @param rest3_period Rest3 period
+ */
+void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period);
+
+/**
+ * @brief Function for setting mouse sensor mode downshift time periods.
+ *
+ * Allowed range for run_to_rest1_mode_time period is 0x00 to 0xFF.
+ * Allowed range for rest1_to_rest2_mode_time period is 0x01 to 0xFF.
+ * Allowed range for rest2_to_rest3_mode_time period is 0x01 to 0xFF.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param run_to_rest1_mode_time Run mode to Rest1 mode downshift time period (Time = run_to_rest1_mode_time * 8 * 4)
+ * @param rest1_to_rest2_mode_time Rest1 mode to Rest2 mode downshift time period (Time = rest1_to_rest2_mode_time * rest1_period * 16)
+ * @param rest2_to_rest3_mode_time Rest2 mode to Rest3 mode downshift time period (Time = rest2_to_rest3_mode_time * rest2_period * 128)
+ */
+void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time);
+
+/**
+ * @brief Function for forcing mouse sensor to a certain operating mode.
+ *
+ * Chip is expected to be initialized before calling this function.
+ * Normal operation will not continue until this function is called with ADNS2080_MODE_NORMAL parameter.
+ *
+ * @param mode Mode to force the sensor to.
+ */
+void adns2080_force_mode_set(adns2080_mode_t mode);
+
+/**
+ * @brief Function for reading the current forced operating mode.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return Mode the sensor is forced to.
+ */
+adns2080_mode_t adns2080_force_mode_read(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c
new file mode 100644
index 0000000..a69bb24
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c
@@ -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.
+ *
+ */
+#include "bh1745.h"
+
+#define BH1745_SENSOR_WRITE(p_instance, msg) \
+ nrf_twi_sensor_write(p_instance->p_sensor_data, \
+ p_instance->sensor_addr, \
+ msg, \
+ ARRAY_SIZE(msg), \
+ true)
+
+ret_code_t bh1745_init(bh1745_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < BH1745_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ static const uint8_t msg1[] = {
+ BH1745_REG_MODE_CONTROL1,
+ 0x00,
+ 0x00,
+ 0x00
+ };
+ ret_code_t err = BH1745_SENSOR_WRITE(p_instance, msg1);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+
+ static const uint8_t msg2[] = {
+ BH1745_REG_INTERRUPT,
+ 0x00,
+ 0x01,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0x00
+ };
+ return BH1745_SENSOR_WRITE(p_instance, msg2);
+}
+
+ret_code_t bh1745_sw_reset(bh1745_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ static const uint8_t send_msg[] = {
+ BH1745_REG_SYSTEM_CONTROL,
+ BH1745_SW_RESET_MASK
+ };
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_int_reset(bh1745_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ static const uint8_t send_msg[] = {
+ BH1745_REG_SYSTEM_CONTROL,
+ BH1745_INT_RESET_MASK
+ };
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_meas_cfg(bh1745_instance_t * p_instance,
+ bh1745_meas_time_t meas_time,
+ bool enable,
+ bh1745_gain_t gain)
+{
+ ASSERT(p_instance != NULL);
+ if (meas_time > BH1745_MEAS_TIME_5120MS)
+ {
+ meas_time = BH1745_MEAS_TIME_5120MS;
+ }
+ if (gain > BH1745_GAIN_16X)
+ {
+ gain = BH1745_GAIN_16X;
+ }
+
+ uint8_t send_msg[] = {
+ BH1745_REG_MODE_CONTROL1,
+ 0,
+ 0,
+ 0x02
+ };
+ NRF_TWI_SENSOR_REG_SET(send_msg[1], BH1745_MEAS_TIME_MASK, BH1745_MEAS_TIME_POS, meas_time);
+ NRF_TWI_SENSOR_REG_SET(send_msg[2], BH1745_RGBC_EN_MASK, BH1745_RGBC_EN_POS, enable);
+ NRF_TWI_SENSOR_REG_SET(send_msg[2], BH1745_ADC_GAIN_MASK, BH1745_ADC_GAIN_POS, gain);
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_data_read(bh1745_instance_t * p_instance,
+ bh1745_data_callback_t user_callback,
+ bh1745_data_t * p_data)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_MODE_CONTROL2,
+ NULL,
+ &p_data->valid,
+ 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_RED_DATA_LSB,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) &p_data->red,
+ BH1745_DATA_REG_NUM);
+ return err_code;
+}
+
+ret_code_t bh1745_int_cfg(bh1745_instance_t * p_instance,
+ bool latch,
+ bh1745_int_source_t source,
+ bool enable,
+ bh1745_persistence_t persistance)
+{
+ ASSERT(p_instance != NULL);
+
+ uint8_t int_reg = 0;
+ NRF_TWI_SENSOR_REG_SET(int_reg, BH1745_INT_ENABLE_MASK, BH1745_INT_ENABLE_POS, enable);
+ NRF_TWI_SENSOR_REG_SET(int_reg, BH1745_INT_SOURCE_MASK, BH1745_INT_SOURCE_POS, source);
+ NRF_TWI_SENSOR_REG_SET(int_reg, BH1745_INT_LATCH_MASK, BH1745_INT_LATCH_POS, latch);
+
+ uint8_t send_msg[] = {
+ BH1745_REG_INTERRUPT,
+ int_reg,
+ persistance
+ };
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_high_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ BH1745_REG_TH_LSB,
+ LSB_16(threshold),
+ MSB_16(threshold)
+ };
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_low_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ BH1745_REG_TL_LSB,
+ LSB_16(threshold),
+ MSB_16(threshold)
+ };
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h
new file mode 100644
index 0000000..2cc31b9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h
@@ -0,0 +1,359 @@
+/**
+ * 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 BH1745_H
+#define BH1745_H
+
+#include "nrf_twi_sensor.h"
+#include "bh1745_internal.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define BH1745_BASE_ADDRESS_LOW 0x38U
+#define BH1745_BASE_ADDRESS_HIGH 0x39U
+
+// Minimum nrf_twi_sensor message buffer size and nrf_twi_mngr queue length.
+#define BH1745_MIN_QUEUE_SIZE 5
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref BH1745_INSTANCE DEF.
+ * After that it has to be initialized using @ref bh1745_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Configuration functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ *
+ * There are designated functions to read status sensor registers e.g. @ref bh1745_sys_ctrl_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * uint8_t part_id = NRF_TWI_SENSOR_REG_VAL_GET(sys_ctrl_reg,
+ * BH1745_PART_ID_MASK,
+ * BH1745_PART_ID_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+
+/**
+ * @brief Measurement time.
+ */
+typedef enum
+{
+ BH1745_MEAS_TIME_160MS,
+ BH1745_MEAS_TIME_320MS,
+ BH1745_MEAS_TIME_640MS,
+ BH1745_MEAS_TIME_1280MS,
+ BH1745_MEAS_TIME_2560MS,
+ BH1745_MEAS_TIME_5120MS
+} bh1745_meas_time_t;
+
+/**
+ * @brief RGBC (red, green, blue, clear) gain setting.
+ */
+typedef enum
+{
+ BH1745_GAIN_1X,
+ BH1745_GAIN_2X,
+ BH1745_GAIN_16X
+} bh1745_gain_t;
+
+/**
+ * @brief Persistence settings.
+ */
+typedef enum
+{
+ BH1745_TOGGLE_EACH_MEASURE,
+ BH1745_UPDATE_EACH_MEASURE,
+ BH1745_UPDATE_EVERY_FOURTH,
+ BH1745_UPDATE_EVERY_EIGHTH
+} bh1745_persistence_t;
+
+/**
+ * @brief Interrupt source settings.
+ */
+typedef enum
+{
+ BH1745_RED_CHANNEL,
+ BH1745_GREEN_CHANNEL,
+ BH1745_BLUE_CHANNEL,
+ BH1745_CLEAR_CHANNEL
+} bh1745_int_source_t;
+
+/**
+ * @brief Measurement result.
+ */
+typedef struct
+{
+ uint16_t red; //!< Raw red color value.
+ uint16_t green; //!< Raw green color value.
+ uint16_t blue; //!< Raw blue color value.
+ uint16_t clear; //!< Raw clear color pass value.
+ uint8_t valid; //!< Mode control 2 register value, used for checking data validity.
+} bh1745_data_t;
+
+/**
+ * @brief RGBC data callback prototype.
+ *
+ * @param result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_user_data Pointer to color data structure.
+ */
+typedef void (* bh1745_data_callback_t)(ret_code_t result, bh1745_data_t * p_user_data);
+
+/**
+ * @brief Macro that creates sensor instance.
+ *
+ * @param[in] _bh1745_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance. @ref NRF_TWI_SENSOR_DEF
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define BH1745_INSTANCE_DEF(_bh1745_inst_name, _p_twi_sensor, _sensor_address) \
+ BH1745_INTERNAL_INSTANCE_DEF(_bh1745_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Function for initializing the BH1745 sensor instance.
+ *
+ * TWI manager queue length has to be at least BH1745_MIN_QUEUE_SIZE.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_init(bh1745_instance_t * p_instance);
+
+/**
+ * @brief Function for resetting the BH1745 registers.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_sw_reset(bh1745_instance_t * p_instance);
+
+/**
+ * @brief Function for resetting the interrupt.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_int_reset(bh1745_instance_t * p_instance);
+
+/**
+ * @brief Function for setting measurement configuration.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ * @param[in] meas_time Measurement time.
+ * @param[in] enable Enable RGBC measurements.
+ * @param[in] gain Measurement gain.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_meas_cfg(bh1745_instance_t * p_instance,
+ bh1745_meas_time_t meas_time,
+ bool enable,
+ bh1745_gain_t gain);
+
+/**
+ * @brief Function for setting interrupt configuration.
+ *
+ * @param p_instance Pointer to sensor instance.
+ * @param latch INT pin latch.
+ * @arg false INT pin is latched until INTERRUPT register is read or initialized.
+ * @arg true INT pin is updated after each measurement.
+ * @param source Interrupt source.
+ * @param enable Enable INT pin.
+ * @param persistence Set persistence.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_int_cfg(bh1745_instance_t * p_instance,
+ bool latch,
+ bh1745_int_source_t source,
+ bool enable,
+ bh1745_persistence_t persistance);
+
+/**
+ * @brief Function for setting high interrupt threshold.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] threshold Threshold value.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_high_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold);
+
+/**
+ * @brief Function for setting low interrupt threshold.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] threshold Threshold value.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_low_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold);
+
+/**
+ * @brief Function for getting the BH1745 data.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ * @param[in] user_callback Callback function created by user.
+ * @param[out] p_data The measurement results.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t bh1745_data_read(bh1745_instance_t * p_instance,
+ bh1745_data_callback_t user_callback,
+ bh1745_data_t * p_data);
+
+/**
+ * @brief Function for reading system control register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t bh1745_sys_ctrl_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading interrupt register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t bh1745_interrupt_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading manufacturer id register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t bh1745_manu_id_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for checking if RGBC data has been updated after last configuration change.
+ *
+ * This function should be used in data callback.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return True if data is valid.
+ */
+__STATIC_INLINE bool bh1745_is_data_valid(bh1745_data_t * p_data);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t bh1745_sys_ctrl_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_SYSTEM_CONTROL,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t bh1745_interrupt_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_INTERRUPT,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t bh1745_manu_id_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_MANUFACTURER_ID,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE bool bh1745_is_data_valid(bh1745_data_t * p_data)
+{
+ return NRF_TWI_SENSOR_REG_VAL_GET(p_data->valid,
+ BH1745_VALID_MASK,
+ BH1745_VALID_POS);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BH1745_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h
new file mode 100644
index 0000000..76b38da
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h
@@ -0,0 +1,180 @@
+/**
+ * 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 BH1745_INTERNAL_H
+#define BH1745_INTERNAL_H
+
+#include "nrf_twi_sensor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define BH1745_BASE_ADDRESS_LOW 0x38U
+#define BH1745_BASE_ADDRESS_HIGH 0x39U
+
+#define BH1745_MIN_QUEUE_SIZE 5
+
+/**
+ * @brief Sensor registers.
+ */
+#define BH1745_REG_SYSTEM_CONTROL 0x40
+#define BH1745_REG_MODE_CONTROL1 0x41
+#define BH1745_REG_MODE_CONTROL2 0x42
+#define BH1745_REG_RED_DATA_LSB 0x50
+#define BH1745_REG_DINT_DATA_LSB 0x58
+#define BH1745_REG_INTERRUPT 0x60
+#define BH1745_REG_PERSISTENCE 0x61
+#define BH1745_REG_TH_LSB 0x62
+#define BH1745_REG_TL_LSB 0x64
+#define BH1745_REG_MANUFACTURER_ID 0x92
+
+#define BH1745_DATA_REG_NUM 8
+
+#define BH1745_MANU_ID 0xE0
+#define BH1745_PART_ID 0x0B
+
+
+/**
+ * @brief System Control register bitmasks.
+ */
+
+// Default value for system control register.
+#define BH1745_DEF_SYSTEM_CONTROL 0x0B
+
+// Bitmasks for sw reset.
+#define BH1745_SW_RESET_POS 7
+#define BH1745_SW_RESET_MASK (1 << BH1745_SW_RESET_POS)
+
+// Bitmasks for int reset.
+#define BH1745_INT_RESET_POS 6
+#define BH1745_INT_RESET_MASK (1 << BH1745_INT_RESET_POS)
+
+// Bitmasks for part id.
+#define BH1745_PART_ID_POS 0
+#define BH1745_PART_ID_MASK (0x3F << BH1745_PART_ID_POS)
+
+
+/**
+ * @brief Mode Control 1 register bitmasks.
+ */
+
+// Bitmasks for meas time.
+#define BH1745_MEAS_TIME_POS 0
+#define BH1745_MEAS_TIME_MASK (0x07 << BH1745_MEAS_TIME_POS)
+
+
+/**
+ * @brief Mode Control 2 register bitmasks.
+ */
+
+// Bitmasks for valid.
+#define BH1745_VALID_POS 7
+#define BH1745_VALID_MASK (1 << BH1745_VALID_POS)
+
+// Bitmasks for rgbc en.
+#define BH1745_RGBC_EN_POS 4
+#define BH1745_RGBC_EN_MASK (1 << BH1745_RGBC_EN_POS)
+
+// Bitmasks for adc gain.
+#define BH1745_ADC_GAIN_POS 0
+#define BH1745_ADC_GAIN_MASK (3 << BH1745_ADC_GAIN_POS)
+
+
+/**
+ * @brief Interrupt register bitmasks.
+ */
+
+// Bitmasks for int status.
+#define BH1745_INT_STATUS_POS 7
+#define BH1745_INT_STATUS_MASK (1 << BH1745_INT_STATUS_POS)
+
+// Bitmasks for int latch.
+#define BH1745_INT_LATCH_POS 4
+#define BH1745_INT_LATCH_MASK (1 << BH1745_INT_LATCH_POS)
+
+// Bitmasks for int source.
+#define BH1745_INT_SOURCE_POS 2
+#define BH1745_INT_SOURCE_MASK (3 << BH1745_INT_SOURCE_POS)
+
+// Bitmasks for int enable.
+#define BH1745_INT_ENABLE_POS 0
+#define BH1745_INT_ENABLE_MASK (1 << BH1745_INT_ENABLE_POS)
+
+
+/**
+ * @brief Persistence register bitmasks.
+ */
+
+// Default value for persistence register.
+#define BH1745_DEF_PERSISTENCE 0x01
+
+// Bitmasks for persistence.
+#define BH1745_PERSISTENCE_POS 0
+#define BH1745_PERSISTENCE_MASK (3 << BH1745_PERSISTENCE_POS)
+
+// Default value for high threshold registers.
+#define BH1745_DEF_TH 0xFFFF
+
+
+/**
+ * @brief Sensor instance information.
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+} bh1745_instance_t;
+
+
+#define BH1745_INTERNAL_INSTANCE_DEF(_bh1745_inst_name, _p_twi_sensor, _sensor_address) \
+ static bh1745_instance_t _bh1745_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address \
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BH1745_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c
new file mode 100644
index 0000000..0c31977
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c
@@ -0,0 +1,225 @@
+/**
+ * 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 "ccs811.h"
+
+#define SWAP_16(arg) ((arg) = (MSB_16(arg) | (LSB_16(arg) << 8)))
+
+ret_code_t ccs811_init(ccs811_instance_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < CCS811_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ static uint8_t const send_msg[] = {
+ CCS811_REG_APP_START
+ };
+ ret_code_t err = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ err = ccs811_drive_mode_set(p_instance, CCS811_MODE_0, false, false);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+ err = ccs811_env_set(p_instance, CCS811_DEFAULT_TEMPERATURE, 0, CCS811_DEFAULT_HUMIDITY, 0);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+ return ccs811_thr_cfg(p_instance,
+ CCS811_DEFAULT_LOW_THR,
+ CCS811_DEFAULT_HIGH_THR,
+ CCS811_DEFAULT_HYSTERESIS);
+}
+
+ret_code_t ccs811_drive_mode_set(ccs811_instance_t const * p_instance,
+ ccs811_drive_mode_t mode,
+ bool drdy_en,
+ bool thr_en)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg = 0;
+ NRF_TWI_SENSOR_REG_SET(reg, CCS811_DRIVE_MODE_MASK, CCS811_DRIVE_MODE_POS, mode);
+ NRF_TWI_SENSOR_REG_SET(reg, CCS811_DATA_READY_MASK, CCS811_DATA_READY_POS, drdy_en);
+ NRF_TWI_SENSOR_REG_SET(reg, CCS811_THRESH_MASK, CCS811_THRESH_POS, thr_en);
+
+ uint8_t send_msg[] = {
+ CCS811_REG_MEAS_MODE,
+ reg
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_alg_data_read(ccs811_instance_t const * p_instance,
+ ccs811_data_callback_t user_cb,
+ ccs811_alg_data_t * p_alg_data,
+ ccs811_last_data_byte_t last)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_alg_data != NULL);
+
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_ALG_RESULT_DATA,
+ (nrf_twi_sensor_reg_cb_t) user_cb,
+ (uint8_t *) p_alg_data,
+ last);
+}
+
+void ccs811_alg_data_process(ccs811_alg_data_t * p_alg_data)
+{
+ ASSERT(p_alg_data != NULL);
+
+ SWAP_16(p_alg_data->eco2);
+ SWAP_16(p_alg_data->tvoc);
+ SWAP_16(p_alg_data->raw);
+}
+
+ret_code_t ccs811_env_set(ccs811_instance_t const * p_instance,
+ int8_t temp_value,
+ uint16_t temp_fraction,
+ uint8_t hum_percent,
+ uint16_t hum_fraction)
+{
+ ASSERT(p_instance != NULL);
+ temp_value += CCS811_TEMPERATURE_OFFSET;
+ if(temp_value < 0)
+ {
+ temp_value = 0;
+ }
+ uint16_t env_temp = ( *((uint16_t *) &temp_value) << CCS811_ENV_TEMP_VALUE_POS)
+ | (temp_fraction & CCS811_ENV_TEMP_FRACTION_MASK);
+ uint16_t env_hum = ( *((uint16_t *) &hum_percent) << CCS811_ENV_HUM_PERCENT_POS)
+ | (hum_fraction & CCS811_ENV_HUM_FRACTION_MASK);
+
+ uint8_t send_msg[] = {
+ CCS811_REG_ENV_DATA,
+ MSB_16(env_temp),
+ LSB_16(env_temp),
+ MSB_16(env_hum),
+ LSB_16(env_hum)
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_thr_cfg(ccs811_instance_t const * p_instance,
+ uint16_t l_to_m,
+ uint16_t m_to_h,
+ uint8_t hysteresis)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ CCS811_REG_THRESHOLDS,
+ MSB_16(l_to_m),
+ LSB_16(l_to_m),
+ MSB_16(m_to_h),
+ LSB_16(m_to_h),
+ hysteresis
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_baseline_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint16_t * p_baseline)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_baseline != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_BASELINE,
+ user_cb,
+ (uint8_t *) p_baseline,
+ 2);
+}
+
+ret_code_t ccs811_baseline_set(ccs811_instance_t const * p_instance, uint16_t baseline)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t * p_base = (uint8_t *) &baseline;
+ uint8_t send_msg[] = {
+ CCS811_REG_BASELINE,
+ p_base[0],
+ p_base[1]
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_sw_reset(ccs811_instance_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ static uint8_t const send_msg[] = {
+ CCS811_REG_SW_RESET,
+ CCS811_SW_RESET_BYTE0,
+ CCS811_SW_RESET_BYTE1,
+ CCS811_SW_RESET_BYTE2,
+ CCS811_SW_RESET_BYTE3
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h
new file mode 100644
index 0000000..6b7b336
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h
@@ -0,0 +1,297 @@
+/**
+ * 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 CCS811_H
+#define CCS811_H
+
+#include "nrf_twi_sensor.h"
+#include "ccs811_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define CCS811_BASE_ADDRESS_LOW 0x5AU
+#define CCS811_BASE_ADDRESS_HIGH 0x5BU
+
+// Minimum nrf_twi_sensor message buffer size and nrf_twi_mngr queue length.
+#define CCS811_MIN_QUEUE_SIZE 6
+
+// Hardware ID register value
+#define CCS811_HARDWARE_ID 0x81
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref CCS811_INSTANCE_DEF.
+ * After that it has to be initialized using @ref ccs811_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Configuration functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ *
+ * There are designated functions to read status sensor registers e.g. @ref ccs811_status_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * bool drdy = NRF_TWI_SENSOR_REG_VAL_GET(status, CCS811_DATA_READY_MASK, CCS811_DATA_READY_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+/**
+ * @brief Drive mode setting.
+ */
+typedef enum
+{
+ CCS811_MODE_0,//!< CCS811_MODE_0 - Idle
+ CCS811_MODE_1,//!< CCS811_MODE_1 - Constant power, measure every second.
+ CCS811_MODE_2,//!< CCS811_MODE_2 - Pulse heating mode, measure every 10 seconds.
+ CCS811_MODE_3,//!< CCS811_MODE_3 - Low power pulse heating mode, measure every 60 seconds.
+ CCS811_MODE_4 //!< CCS811_MODE_4 - Constant power, measure every 250ms, only raw data.
+} ccs811_drive_mode_t;
+
+/**
+ * @brief Last byte read from algorithm data.
+ *
+ * Used with @ref ccs811_alg_data_read function, defines to which byte data should be read.
+ */
+typedef enum
+{
+ CCS811_LAST_ECO2 = 2,
+ CCS811_LAST_TVOC = 4,
+ CCS811_LAST_STATUS,
+ CCS811_LAST_ERROR_ID,
+ CCS811_LAST_RAW = 8
+} ccs811_last_data_byte_t;
+
+/**
+ * @brief Structure for holding algorithm data.
+ */
+typedef struct
+{
+ uint16_t eco2; //!< eC02 value in ppm.
+ uint16_t tvoc; //!< TVOC value in ppb.
+ uint8_t status; //!< Status register data.
+ uint8_t error_id; //!< Error register data.
+ uint16_t raw; //!< Raw data.
+} ccs811_alg_data_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Return code from TWI manager and underlying drivers.
+ * @param[in] p_data Pointer to sensor data.
+ */
+typedef void (* ccs811_data_callback_t)(ret_code_t result, ccs811_alg_data_t * p_data);
+
+/**
+ * @brief Macro that creates sensor instance.
+ *
+ * @param[in] _ccs811_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance.
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define CCS811_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address) \
+ CCS811_INTERNAL_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Function initializing ccs811 sensor
+ *
+ * TWI manager queue length has to be at least CCS811_MIN_QUEUE_SIZE
+ *
+ * @param[in] p_instance Pointer to sensor instance created by macro
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_init(ccs811_instance_t const * p_instance);
+
+/**
+ * @brief Function for setting drive mode.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] mode Drive mode.
+ * @param[in] drdy_en Enable data ready pin.
+ * @param[in] thr_en Enable threshold.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_drive_mode_set(ccs811_instance_t const * p_instance,
+ ccs811_drive_mode_t mode,
+ bool drdy_en,
+ bool thr_en);
+
+/**
+ * @brief Function for reading sensor data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after data read.
+ * @param[out] p_alg_data Pointer to structure holding sensor algorithm data.
+ * @param[in] last Last byte to read.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t ccs811_alg_data_read(ccs811_instance_t const * p_instance,
+ ccs811_data_callback_t user_cb,
+ ccs811_alg_data_t * p_alg_data,
+ ccs811_last_data_byte_t last);
+
+/**
+ * @brief Function for processing algorithm data
+ *
+ * @param[in/out] p_alg_data Pointer to read data to be processed.
+ */
+void ccs811_alg_data_process(ccs811_alg_data_t * p_alg_data);
+
+/**
+ * @brief Function for setting environment temperature.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] temp_value Temperature value (-25 to 100 degree celsius).
+ * @param[in] temp_fraction Temperature fraction.
+ * @param[in] hum_percent Humidity percent.
+ * @param[in] hum_fraction Humidity fraction.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_env_set(ccs811_instance_t const * p_instance,
+ int8_t temp_value,
+ uint16_t temp_fraction,
+ uint8_t hum_percent,
+ uint16_t hum_fraction);
+
+/**
+ * @brief Function for threshold configuration
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] l_to_m Low to medium threshold.
+ * @param[in] m_to_h Medium to high threshold.
+ * @param[in] hysteresis Hysteresis.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_thr_cfg(ccs811_instance_t const * p_instance,
+ uint16_t l_to_m,
+ uint16_t m_to_h,
+ uint8_t hysteresis);
+
+/**
+ * @brief Function for reading baseline.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after baseline read.
+ * @param[out] baseline Baseline value, single uint16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t ccs811_baseline_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint16_t * p_baseline);
+
+/**
+ * @brief Function for setting baseline.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] baseline Baseline value.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_baseline_set(ccs811_instance_t const * p_instance,
+ uint16_t baseline);
+
+/**
+ * @brief Function commencing software reset.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @note To use sensor after reset, it has to be initialized again using @ref ccs811_init function.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_sw_reset(ccs811_instance_t const * p_instance);
+
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] p_reg_val Pointer to register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t ccs811_status_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val);
+
+/**
+ * @brief Function for reading hardware id register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] p_reg_val Pointer to register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t ccs811_hw_id_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val);
+
+/**
+ * @brief Function for reading error id register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] p_reg_val Pointer to register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t ccs811_error_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CCS811_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h
new file mode 100644
index 0000000..423e61d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h
@@ -0,0 +1,259 @@
+/**
+ * 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 CCS811_INTERNAL_H
+#define CCS811_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief CCS811 sensor registers.
+ */
+#define CCS811_REG_STATUS 0x00
+#define CCS811_REG_MEAS_MODE 0x01
+#define CCS811_REG_ALG_RESULT_DATA 0x02
+#define CCS811_REG_RAW_DATA 0x03
+#define CCS811_REG_ENV_DATA 0x05
+#define CCS811_REG_NTC 0x06
+#define CCS811_REG_THRESHOLDS 0x10
+#define CCS811_REG_BASELINE 0x11
+#define CCS811_REG_HW_ID 0x20
+#define CCS811_REG_HW_VER 0x21
+#define CCS811_REG_FW_BOOT_VER 0x23
+#define CCS811_REG_FW_APP_VER 0x24
+#define CCS811_REG_ERROR_ID 0xE0
+#define CCS811_REG_SW_RESET 0xFF
+#define CCS811_REG_APP_START 0xF4
+
+/**
+ * @brief CCS811 Default configuration values.
+ */
+#define CCS811_DEFAULT_HUMIDITY 50
+#define CCS811_DEFAULT_TEMPERATURE 25
+#define CCS811_DEFAULT_LOW_THR 1500
+#define CCS811_DEFAULT_HIGH_THR 2500
+#define CCS811_DEFAULT_HYSTERESIS 50
+
+/**
+ * @brief CCS811 Environment temperature offset.
+ */
+#define CCS811_TEMPERATURE_OFFSET 25
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for FW_MODE.
+#define CCS811_FW_MODE_POS 7
+#define CCS811_FW_MODE_MASK (1 << CCS811_FW_MODE_POS)
+
+// Bitmasks for APP_VALID.
+#define CCS811_APP_VALID_POS 4
+#define CCS811_APP_VALID_MASK (1 << CCS811_APP_VALID_POS)
+
+// Bitmasks for DATA_READY.
+#define CCS811_DATA_READY_POS 3
+#define CCS811_DATA_READY_MASK (1 << CCS811_DATA_READY_POS)
+
+// Bitmasks for ERROR.
+#define CCS811_ERROR_POS 0
+#define CCS811_ERROR_MASK (1 << CCS811_ERROR_POS)
+
+
+/**
+ * @brief Meas mode register bitmasks.
+ */
+
+// Register validity mask.
+#define CCS811_MEAS_MODE_VALID_MASK 0x83U
+
+// Bitmasks for DRIVE_MODE.
+#define CCS811_DRIVE_MODE_POS 4
+#define CCS811_DRIVE_MODE_MASK (7 << CCS811_DRIVE_MODE_POS)
+
+// Bitmasks for INTERRUPT.
+#define CCS811_INTERRUPT_POS 3
+#define CCS811_INTERRUPT_MASK (1 << CCS811_INTERRUPT_MASK)
+
+// Bitmasks for THRESH.
+#define CCS811_THRESH_POS 2
+#define CCS811_THRESH_MASK (1 << CCS811_THRESH_POS)
+
+/**
+ * @brief Algorithm results data bytes.
+ */
+
+#define CCS811_ALG_RESULT_BYTE_NUM 8
+#define CCS811_ALG_ECO2_H_BYTE 0
+#define CCS811_ALG_ECO2_L_BYTE 1
+#define CCS811_ALG_TVOC_H_BYTE 2
+#define CCS811_ALG_TVOC_L_BYTE 3
+#define CCS811_ALG_STATUS_BYTE 4
+#define CCS811_ALG_ERROR_BYTE 5
+#define CCS811_ALG_RAW_DATA1_BYTE 6
+#define CCS811_ALG_RAW_DATA2_BYTE 7
+
+/**
+ * @brief Environment data register.
+ */
+
+#define CCS811_ENV_HUMIDITY_H_BYTE 0
+
+// Humidity percent position.
+#define CCS811_ENV_HUM_PERCENT_POS 9
+
+// Bitmasks for humidity fraction.
+#define CCS811_ENV_HUM_FRACTION_MASK (0x01FF)
+
+
+// Temperature value position.
+#define CCS811_ENV_TEMP_VALUE_POS 9
+
+// Bitmasks for temperature fraction.
+#define CCS811_ENV_TEMP_FRACTION_MASK (0x01FF)
+
+
+/**
+ * @brief Error register.
+ */
+
+// Bitmasks for HEATER_SUPPLY
+#define CCS811_ERROR_HEATER_SUPPLY_POS 5
+#define CCS811_ERROR_HEATER_SUPPLY_MASK (1 << CCS811_ERROR_HEATER_SUPPLY_POS)
+
+// Bitmasks for HEATER_FAULT
+#define CCS811_ERROR_HEATER_FAULT_POS 4
+#define CCS811_ERROR_HEATER_FAULT_MASK (1 << CCS811_ERROR_HEATER_FAULT_POS)
+
+// Bitmasks for MAX_RESISTANCE
+#define CCS811_ERROR_MAX_RESISTANCE_POS 3
+#define CCS811_ERROR_MAX_RESISTANCE_MASK (1 << CCS811_ERROR_MAX_RESISTANCE_POS)
+
+// Bitmasks for MEASMODE_INVALID
+#define CCS811_ERROR_MEAS_MODE_POS 2
+#define CCS811_ERROR_MEAS_MODE_MASK (1 CCS811_ERROR_MEAS_MODE_POS)
+
+// Bitmasks for READ_REG
+#define CCS811_ERROR_READ_REG_POS 1
+#define CCS811_ERROR_READ_REG_MASK (1 << CCS811_ERROR_READ_REG_POS)
+
+// Bitmasks for WRITE_REG
+#define CCS811_ERROR_WRITE_REG_POS 0
+#define CCS811_ERROR_WRITE_REG_MASK (1 << CCS811_ERROR_WRITE_REG_POS)
+
+/**
+ * @brief Software reset register.
+ */
+#define CCS811_SW_RESET_BYTE0 0x11
+#define CCS811_SW_RESET_BYTE1 0xE5
+#define CCS811_SW_RESET_BYTE2 0x72
+#define CCS811_SW_RESET_BYTE3 0x8A
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+} ccs811_instance_t;
+
+/**
+ * @brief Macro that creates sensor instance.
+ */
+#define CCS811_INTERNAL_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address) \
+ static ccs811_instance_t _ccs811_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address, \
+ }
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t ccs811_status_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_reg_val != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_STATUS,
+ user_cb,
+ p_reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t ccs811_hw_id_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_reg_val != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_HW_ID,
+ user_cb,
+ p_reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t ccs811_error_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_reg_val != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_ERROR_ID,
+ user_cb,
+ p_reg_val,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CCS811_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c
new file mode 100644
index 0000000..ce087db
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c
@@ -0,0 +1,474 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 "cherry8x16.h"
+#include "nrf.h"
+
+#define CHERRY8x16_NUM_OF_COLUMNS 16 // !< Number of columns in the keyboard matrix
+#define CHERRY8x16_NUM_OF_ROWS 8 // !< Number of rows in the keyboard matrix
+
+#define MODIFIER_HID_START 0xE0
+#define MODIFIER_HID_END 0xE7
+static uint8_t m_currently_pressed_keys[CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS]; //!< Array holding currently pressed keys. Filled up from index 0. Values are
+static uint8_t m_transmitted_keys[CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS]; //!< Array holding the keys that have already been transmitted.
+static uint8_t m_num_of_currently_pressed_keys; //!< Number of keys in m_currently_pressed_keys
+static uint8_t m_number_of_transmitted_keys; //!< Number of keys in m_transmitted_keys
+
+static uint8_t m_key_packet[KEY_PACKET_SIZE]; //!< Stores last created key packet. One byte is used for modifier keys, one for OEMs. Key values are USB HID keycodes.
+
+static const uint8_t volatile * m_row_port; //!< Pointer to location where row IO can be read
+static uint16_t volatile * m_column_port; //!< Pointer to location where column IO can be written
+static const uint8_t * matrix_lookup; //!< Pointer to the key lookup matrix in use
+
+/** Table containing the mapping between the key matrix and the HID Usage codes for each key. */
+static const uint8_t default_matrix_lookup[CHERRY8x16_NUM_OF_COLUMNS * CHERRY8x16_NUM_OF_ROWS] =
+{
+ 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE1, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE2, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x29, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x3F, 0x40,
+ 0x1E, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x24, 0x25,
+ 0x4F, 0x43, 0x47, 0x53, 0x46, 0x48, 0x42, 0x41,
+ 0x51, 0x2D, 0x2E, 0x2A, 0x00, 0x4A, 0x27, 0x26,
+ 0x52, 0x13, 0x2F, 0x30, 0x00, 0x4B, 0x12, 0x0C,
+ 0x50, 0x33, 0x34, 0x32, 0x28, 0x4E, 0x0F, 0x0E,
+ 0x2C, 0x38, 0x4C, 0x49, 0x65, 0x4D, 0x37, 0x36,
+ 0x35, 0x05, 0x19, 0x06, 0x1B, 0x1D, 0x11, 0x10,
+ 0x39, 0x0A, 0x09, 0x07, 0x16, 0x04, 0x0B, 0x0D,
+ 0x2B, 0x17, 0x15, 0x08, 0x1A, 0x14, 0x1C, 0x18
+};
+
+static bool cherry8x16_have_keys_changed(const uint8_t * state_now,
+ uint8_t number_of_now_pressed_keys,
+ const uint8_t * state_before,
+ uint8_t number_of_before_pressed_keys);
+static bool cherry8x16_keymatrix_read(uint8_t * pressed_keys, uint8_t * number_of_pressed_keys);
+static void cherry8x16_keypacket_addkey(uint8_t key);
+static void cherry8x16_keypacket_create(uint8_t * key_packet, uint8_t key_packet_size);
+static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys);
+static uint8_t cherry8x16_row_read(void);
+
+cherry8x16_status_t cherry8x16_init(const uint8_t volatile * row_port,
+ uint16_t * column_port,
+ const uint8_t * key_lookup_matrix)
+{
+ cherry8x16_status_t status = CHERRY8x16_OK;
+
+ if (row_port == 0 || column_port == 0)
+ {
+ status = CHERRY8x16_INVALID_PARAMETER;
+ }
+ else
+ {
+ m_row_port = row_port;
+ m_column_port = column_port;
+
+ *m_column_port = 0x0000;
+ if (*m_row_port != 0x00)
+ {
+ status = CHERRY8x16_NOT_DETECTED;
+ }
+ else
+ {
+ m_num_of_currently_pressed_keys = 0;
+ m_number_of_transmitted_keys = 0;
+
+ for (uint_fast8_t i = CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS; i--;)
+ {
+ m_currently_pressed_keys[i] = 0;
+ m_transmitted_keys[i] = 0;
+ }
+ }
+
+ if (key_lookup_matrix == CHERRY8x16_DEFAULT_KEY_LOOKUP_MATRIX)
+ {
+ matrix_lookup = default_matrix_lookup;
+ }
+ else
+ {
+ matrix_lookup = key_lookup_matrix;
+ }
+ }
+
+ return status;
+}
+
+bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t * p_key_packet_size)
+{
+ bool new_packet_prepared;
+
+ // Save currently pressed keys
+ for (uint_fast8_t i = CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS; i--; )
+ {
+ m_transmitted_keys[i] = m_currently_pressed_keys[i];
+ }
+ m_number_of_transmitted_keys = m_num_of_currently_pressed_keys;
+
+ // Create a new packet if key states have changed and there are no keys blocking each other (ghosting/phantom keys)
+ if (cherry8x16_keymatrix_read(m_currently_pressed_keys, &m_num_of_currently_pressed_keys))
+ {
+ if (cherry8x16_have_keys_changed(m_currently_pressed_keys, m_num_of_currently_pressed_keys,
+ m_transmitted_keys, m_number_of_transmitted_keys))
+ {
+ cherry8x16_keypacket_create(&m_key_packet[0], KEY_PACKET_SIZE);
+ *p_key_packet = &m_key_packet[0];
+ *p_key_packet_size = KEY_PACKET_SIZE;
+ new_packet_prepared = true;
+ }
+ else
+ {
+ // The same keys are still pressed, no need to create a new packet
+ new_packet_prepared = false;
+ }
+ }
+ else
+ {
+ // Ghosting detected. Don't create a packet.
+ new_packet_prepared = false;
+ }
+
+ return new_packet_prepared;
+}
+
+
+/**
+ * @brief Function for reading and returning keyboard matrix row state.
+ *
+ * @return uint8_t Row state
+ */
+static uint8_t cherry8x16_row_read(void)
+{
+ return *m_row_port;
+}
+
+
+/**
+ * @brief Function for reading the keyboard matrix state and stores the pressed keys to an array.
+ *
+ * This function resolves keys from the matrix and finds their corresponding HID usage codes
+ * If there are any ghost key conditions the packet will be discarded
+ * @param pressed_keys Array holding pressed keys. Must be at least CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS in size.
+ * @param number_of_pressed_keys Pointer to variable where number of pressed keys will be stored.
+ * @return
+ * @retval true If no keys were blocking each other.
+ * @retval false If some keys were blocking each other o rno key is pressed.
+ */
+static bool cherry8x16_keymatrix_read(uint8_t * pressed_keys, uint8_t * number_of_pressed_keys)
+{
+ uint_fast8_t row_state[CHERRY8x16_NUM_OF_COLUMNS];
+ uint_fast8_t blocking_mask = 0;
+
+ *number_of_pressed_keys = 0;
+
+ for (uint_fast8_t column = CHERRY8x16_NUM_OF_COLUMNS; column--;)
+ {
+ // drive column under test
+ *m_column_port = (uint16_t)(1UL << column);
+ row_state[column] = cherry8x16_row_read();
+
+ // Check if any keys are pressed
+ if (row_state[column] != 0)
+ {
+ uint_fast8_t detected_keypresses_on_column = 0;
+
+ // Loop through rows, check for active rows and add pressed keys to the array
+ for (uint_fast8_t row = CHERRY8x16_NUM_OF_ROWS; row--;)
+ {
+ if (row_state[column] & (1U << row))
+ {
+ if (*number_of_pressed_keys < CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS)
+ {
+ *pressed_keys = matrix_lookup[column * CHERRY8x16_NUM_OF_ROWS + row];
+ pressed_keys++;
+ (*number_of_pressed_keys)++;
+ }
+ detected_keypresses_on_column++;
+ }
+ }
+
+ if (detected_keypresses_on_column > 1)
+ {
+ if (blocking_mask & row_state[column])
+ {
+ // Cannot determine reliably all pressed keys, two or more keys are blocking each other.
+ return false;
+ }
+ }
+ blocking_mask |= row_state[column];
+ }
+ }
+
+ return true;
+}
+
+
+/**
+ * @brief Function for remapping the keypad, F11 and F12 keys in case when Fn key is pressed.
+ *
+ * @param keys Array holding pressed keys.
+ * @param number_of_keys Number of elements if 'keys' array.
+ */
+static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys)
+{
+
+ /*lint -e845 -save // A zero has been given as right argument to operator '<<'" */
+ /*lint -e778 -save // Constant expression evaluates to zero */
+
+#define MODIFIER_LEFT_CONTROL_HID 0xE0
+#define MODIFER_RIGHT_CONTROL_HID 0xE4
+ // Check if Fn key is pressed along with any other modifier key (only usage now is Fn + Left_Ctrl = Right Ctrl)
+ // So we modify the modifier byte if Fn + Left_Ctrl is pressed, HID for left_Ctrl = 0xE0
+ if ( keys[0] & (1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START)) )
+ {
+ keys[0] &= ~(1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START));
+ keys[0] |= (1UL << (MODIFER_RIGHT_CONTROL_HID - MODIFIER_HID_START));
+ }
+
+ /*lint -restore */
+ /*lint -restore */
+
+ for (uint_fast8_t i = 2; i < number_of_keys; i++)
+ {
+ switch (keys[i])
+ {
+ case 0x10: // 'M'
+ keys[i] = 0x62; // Keypad 0
+ break;
+
+ case 0x37: // '>'
+ keys[i] = 0x63; // Keypad .
+ break;
+
+ case 0x38: // '/'
+ keys[i] = 0x54; // Keypad /
+ break;
+
+ case 0x0D: // 'J'
+ keys[i] = 0x59; // Keypad 1
+ break;
+
+ case 0x0E: // 'K'
+ keys[i] = 0x5A; // Keypad 2
+ break;
+
+ case 0x0F: // 'L'
+ keys[i] = 0x5B; // Keypad 3
+ break;
+
+ case 0x33: // ''
+ keys[i] = 0x57; // Keypad +
+ break;
+
+ case 0x28: // 'Enter'
+ keys[i] = 0x58; // Keypad enter
+ break;
+
+ case 0x18: // 'U'
+ keys[i] = 0x5C; // Keypad 4
+ break;
+
+ case 0x0C: // 'I'
+ keys[i] = 0x5D; // Keypad 5
+ break;
+
+ case 0x12: // 'O'
+ keys[i] = 0x5E; // Keypad 6
+ break;
+
+ case 0x13: // 'P'
+ keys[i] = 0x56; // Keypad -
+ break;
+
+ case 0x24: // '7'
+ keys[i] = 0x5F; // Keypad 7
+ break;
+
+ case 0x25: // '8'
+ keys[i] = 0x60; // Keypad 8
+ break;
+
+ case 0x26: // '9'
+ keys[i] = 0x61; // Keypad 9
+ break;
+
+ case 0x27: // '0'
+ keys[i] = 0x55; // Keypad *
+ break;
+
+ case 0x3A: // 'F1'
+ keys[i] = 0x44; // 'F11'
+ break;
+
+ case 0x3B: // 'F2'
+ keys[i] = 0x45; // 'F12'
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/**
+ * @brief Function for determining whether the keyboard matrix state has changed compared to the state before.
+ *
+ * @param state_now List of pressed keys in current state
+ * @param number_of_now_pressed_keys Number of pressed keys in current state
+ * @param state_before List of pressed keys in previous state
+ * @param number_of_before_pressed_keys Number of pressed keys in previous state
+ * @return
+ * @retval true If keyboard matrix is different compared to state before.
+ * @retval false If keyboard matrix is the same compared to state before.
+ */
+static bool cherry8x16_have_keys_changed(const uint8_t * state_now,
+ uint8_t number_of_now_pressed_keys,
+ const uint8_t * state_before,
+ uint8_t number_of_before_pressed_keys)
+{
+ if (number_of_now_pressed_keys != number_of_before_pressed_keys)
+ {
+ return true;
+ }
+ else
+ {
+ for (uint_fast8_t i = number_of_now_pressed_keys; i--;)
+ {
+ if (state_now[i] != state_before[i])
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief Function for adding a key to the key packet.
+ *
+ * If key is found to be in the packet, it will not be added twice.
+ * Attempts to add more keys than the buffer capacity allows will be silently ignored.
+ *
+ * @param key Key to add
+ */
+static void cherry8x16_keypacket_addkey(uint8_t key)
+{
+ for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < KEY_PACKET_SIZE; i++)
+ {
+ if (m_key_packet[i] == key)
+ {
+ return;
+ }
+ }
+
+ for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < KEY_PACKET_SIZE; i++)
+ {
+ if (m_key_packet[i] == KEY_PACKET_NO_KEY)
+ {
+ m_key_packet[i] = key;
+ return;
+ }
+ }
+}
+
+/**
+ * @brief Function for creating a new key packet.
+ *
+ * This function uses @ref m_currently_pressed_keys to determine pressed keys.
+ * Priority is given to those keys that were found in the previous packet.
+ * All modifier keys can be found in all packets.
+ * If Fn key is detected to be pressed, some keys are remapped to different functions.
+ *
+ * @param key_packet Pointer to location where packet contents will be put
+ * @param key_packet_size Key packet size in bytes
+ */
+static void cherry8x16_keypacket_create(uint8_t * key_packet, uint8_t key_packet_size)
+{
+ // Clear key_packet contents
+ for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < key_packet_size; i++)
+ {
+ key_packet[i] = KEY_PACKET_NO_KEY;
+ }
+ key_packet[KEY_PACKET_MODIFIER_KEY_INDEX] = 0;
+ key_packet[KEY_PACKET_RESERVED_INDEX] = 0;
+
+ // Give priority to keys that were already pressed when we transmitted them the last time.
+ for (uint_fast8_t i = 0; i < m_number_of_transmitted_keys; i++)
+ {
+ for (uint_fast8_t j = 0; j < m_num_of_currently_pressed_keys; j++)
+ {
+ if (m_transmitted_keys[i] == m_currently_pressed_keys[j])
+ {
+ cherry8x16_keypacket_addkey(m_currently_pressed_keys[j]);
+ break;
+ }
+ }
+ }
+
+ bool fn_key_is_set = false;
+
+ // Detect if Fn is pressed, detect modifier keys, and add rest of the keys to the packet
+ for (uint_fast8_t i = 0; i < m_num_of_currently_pressed_keys; i++)
+ {
+ if (m_currently_pressed_keys[i] == 0xFF) // Pressing Fn key changes function of certain keys and it must handled by the firmware
+ {
+ fn_key_is_set = true;
+ }
+ // Modifier HID usage codes are from 0xE0 to 0xE7
+ else if (m_currently_pressed_keys[i] >= MODIFIER_HID_START && m_currently_pressed_keys[i] <= MODIFIER_HID_END) // Detect and set modifier keys
+ {
+ key_packet[KEY_PACKET_MODIFIER_KEY_INDEX] |= (uint8_t)(1U << (m_currently_pressed_keys[i] - MODIFIER_HID_START));
+ }
+ else if (m_currently_pressed_keys[i] != 0)
+ {
+ cherry8x16_keypacket_addkey(m_currently_pressed_keys[i]);
+ }
+ }
+
+ if (fn_key_is_set)
+ {
+ cherry8x16_remap_fn_keys(&key_packet[0], KEY_PACKET_MAX_KEYS);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h
new file mode 100644
index 0000000..b4e099d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef CHERRY8x16_H
+#define CHERRY8x16_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief Cherry 8x16 keyboard matrix driver
+*
+*
+* @defgroup nrf_drivers_cherry8x16 Cherry 8x16 keyboard matrix driver
+* @{
+* @ingroup ext_drivers
+* @brief Cherry 8x16 keyboard matrix driver.
+*/
+
+#define CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS 6 //!< Maximum number of pressed keys kept in buffers
+#define CHERRY8x16_DEFAULT_KEY_LOOKUP_MATRIX (const uint8_t*)0 //!< If passed to @ref cherry8x16_init, default lookup matrix will be used
+
+#define KEY_PACKET_MODIFIER_KEY_INDEX (0) //!< Index in the key packet where modifier keys such as ALT and Control are stored
+#define KEY_PACKET_RESERVED_INDEX (1) //!< Index in the key packet where OEMs can store information
+#define KEY_PACKET_KEY_INDEX (2) //!< Start index in the key packet where pressed keys are stored
+#define KEY_PACKET_MAX_KEYS (6) //!< Maximum number of keys that can be stored into the key packet
+#define KEY_PACKET_SIZE (KEY_PACKET_KEY_INDEX + KEY_PACKET_MAX_KEYS) //!< Total size of the key packet in bytes
+#define KEY_PACKET_NO_KEY (0) //!< Value to be stored to key index to indicate no key is pressed
+
+
+/**
+ * Describes return values for:
+ * @ref cherry8x16_init
+ */
+typedef enum
+{
+ CHERRY8x16_OK, /*!< Operation was succesful. */
+ CHERRY8x16_NOT_DETECTED, /*!< Product/Revision ID was not what was expected */
+ CHERRY8x16_INVALID_PARAMETER /*!< Given parameters were not valid */
+} cherry8x16_status_t;
+
+/**
+ * @brief Function for initializing the driver.
+ *
+ * @note Before calling this function, setup row_port as IO inputs with pulldowns enabled and column_port as IO outputs.
+ *
+ * @param row_port Pointer to GPIO port address that is used as key matrix row input.
+ * @param column_port Pointer to GPIO port address that is used as key matrix column output.
+ * @param key_lookup_matrix If NULL, use a default key lookup matrix. Otherwise pointer to a 128 (8x16) element array containing HID keycodes.
+ * @return
+ * @retval CHERRY8X16_OK Peripheral was initialized succesfully.
+ * @retval CHERRY8X16_NOT_DETECTED Could not detect the peripheral.
+ */
+cherry8x16_status_t cherry8x16_init(const uint8_t volatile * row_port, uint16_t * column_port, const uint8_t * key_lookup_matrix);
+
+/**
+ * @brief Function for creating a new key packet if new data is available and key ghosting is not detected.
+ *
+ * @param p_key_packet Array that will hold the created key packet. Previously created packet will be discarded.
+ * @param p_key_packet_size Key packet size in bytes.
+ * @return
+ * @retval true If new packet was created.
+ * @retval false If packet was not created.
+ */
+bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t *p_key_packet_size);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c
new file mode 100644
index 0000000..ac4da3b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c
@@ -0,0 +1,154 @@
+/**
+ * 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 "ds1624.h"
+#include "twi_master.h"
+#include "nrf_delay.h"
+
+/*lint ++flb "Enter library region" */
+
+#define DS1634_BASE_ADDRESS 0x90 //!< 4 MSBs of the DS1624 TWI address
+
+#define DS1624_ONESHOT_MODE 0x01 //!< Bit in configuration register for 1-shot mode
+#define DS1624_CONVERSION_DONE 0x80 //!< Bit in configuration register to indicate completed temperature conversion
+
+static uint8_t m_device_address; //!< Device address in bits [7:1]
+
+const uint8_t command_access_memory = 0x17; //!< Reads or writes to 256-byte EEPROM memory
+const uint8_t command_access_config = 0xAC; //!< Reads or writes configuration data to configuration register
+const uint8_t command_read_temp = 0xAA; //!< Reads last converted temperature value from temperature register
+const uint8_t command_start_convert_temp = 0xEE; //!< Initiates temperature conversion.
+const uint8_t command_stop_convert_temp = 0x22; //!< Halts temperature conversion.
+
+/**
+ * @brief Function for reading the current configuration of the sensor.
+ *
+ * @return uint8_t Zero if communication with the sensor failed. Contents (always non-zero) of configuration register (@ref DS1624_ONESHOT_MODE and @ref DS1624_CONVERSION_DONE) if communication succeeded.
+ */
+static uint8_t ds1624_config_read(void)
+{
+ uint8_t config = 0;
+
+ // Write: command protocol
+ if (twi_master_transfer(m_device_address, (uint8_t*)&command_access_config, 1, TWI_DONT_ISSUE_STOP))
+ {
+ if (twi_master_transfer(m_device_address | TWI_READ_BIT, &config, 1, TWI_ISSUE_STOP)) // Read: current configuration
+ {
+ // Read succeeded, configuration stored to variable "config"
+ }
+ else
+ {
+ // Read failed
+ config = 0;
+ }
+ }
+
+ return config;
+}
+
+bool ds1624_init(uint8_t device_address)
+{
+ bool transfer_succeeded = true;
+ m_device_address = DS1634_BASE_ADDRESS + (uint8_t)(device_address << 1);
+
+ uint8_t config = ds1624_config_read();
+
+ if (config != 0)
+ {
+ // Configure DS1624 for 1SHOT mode if not done so already.
+ if (!(config & DS1624_ONESHOT_MODE))
+ {
+ uint8_t data_buffer[2];
+
+ data_buffer[0] = command_access_config;
+ data_buffer[1] = DS1624_ONESHOT_MODE;
+
+ transfer_succeeded &= twi_master_transfer(m_device_address, data_buffer, 2, TWI_ISSUE_STOP);
+ }
+ }
+ else
+ {
+ transfer_succeeded = false;
+ }
+
+ return transfer_succeeded;
+}
+
+bool ds1624_start_temp_conversion(void)
+{
+ return twi_master_transfer(m_device_address, (uint8_t*)&command_start_convert_temp, 1, TWI_ISSUE_STOP);
+}
+
+bool ds1624_is_temp_conversion_done(void)
+{
+ uint8_t config = ds1624_config_read();
+
+ if (config & DS1624_CONVERSION_DONE)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool ds1624_temp_read(int8_t * temperature_in_celcius, int8_t * temperature_fraction)
+{
+ bool transfer_succeeded = false;
+
+ // Write: Begin read temperature command
+ if (twi_master_transfer(m_device_address, (uint8_t*)&command_read_temp, 1, TWI_DONT_ISSUE_STOP))
+ {
+ uint8_t data_buffer[2];
+
+ // Read: 2 temperature bytes to data_buffer
+ if (twi_master_transfer(m_device_address | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP))
+ {
+ *temperature_in_celcius = (int8_t)data_buffer[0];
+ *temperature_fraction = (int8_t)data_buffer[1];
+
+ transfer_succeeded = true;
+ }
+ }
+
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h
new file mode 100644
index 0000000..e331119
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef DS1624_H
+#define DS1624_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief DS1624 digital temperature sensor driver.
+*
+*
+* @defgroup nrf_drivers_ds1624 DS1624 digital temperature sensor driver
+* @{
+* @ingroup ext_drivers
+* @brief DS1624 digital temperature sensor driver.
+*/
+
+/**
+ * @brief Function for initializing DS1624 temperature sensor to 1-shot mode.
+ *
+ * @note Before calling this function, you must initialize twi_master first.
+ *
+ * @param device_address Bits [2:0] for the device address. All other bits must be zero.
+ * @return
+ * @retval true If communication succeeded with the device.
+ * @retval false If communication failed with the device.
+ */
+bool ds1624_init(uint8_t device_address);
+
+/**
+ * @brief Function for reading temperature from the sensor.
+ *
+ * @param temperature_in_celcius Memory location to store temperature in full celcius degrees.
+ * @param temperature_fraction Memory location to store temperature's fraction part in 0.03125 celcius degree increments.
+ * @return
+ * @retval true Temperature was successfully read
+ * @retval false Temperature reading failed or conversion was not yet complete
+ */
+bool ds1624_temp_read(int8_t *temperature_in_celcius, int8_t *temperature_fraction);
+
+/**
+ * @brief Function for starting temperature conversion. Valid data will be available 400 - 1000 milliseconds after exiting this function.
+ *
+ * @return
+ * @retval true Temperature conversion started.
+ * @retval false Temperature converion failed to start.
+*/
+bool ds1624_start_temp_conversion(void);
+
+/**
+ * @brief Function for checking if temperature conversion is done.
+ *
+ * @return
+ * @retval true Temperature conversion done.
+ * @retval false Temperature converion still in progress.
+*/
+bool ds1624_is_temp_conversion_done(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c
new file mode 100644
index 0000000..ce77d60
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c
@@ -0,0 +1,255 @@
+/**
+ * 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 "hts221.h"
+#include <string.h>
+
+#define HTS221_WRITE(p_instance, msg) \
+ nrf_twi_sensor_write(p_instance->p_sensor_data, \
+ p_instance->sensor_addr, \
+ msg, \
+ ARRAY_SIZE(msg), \
+ true)
+
+static void hts221_init_cb(ret_code_t result, void * p_register_data)
+{
+ hts221_calib_t * calib_info = (hts221_calib_t *) p_register_data;
+ uint8_t calib_raw[HTS221_REG_CALIBRATION_NUM];
+ memcpy(calib_raw, calib_info, HTS221_REG_CALIBRATION_NUM);
+
+ calib_info->H0_rH_x2 = calib_raw[0];
+ calib_info->H1_rH_x2 = calib_raw[1];
+ calib_info->T0_degC_x8 = (uint16_t)calib_raw[2]
+ + ((uint16_t)(calib_raw[5] & 0x03) << 8);
+ calib_info->T1_degC_x8 = (uint16_t)calib_raw[3]
+ + ((uint16_t)((calib_raw[5] >> 2) & 0x03) << 8);
+ calib_info->H0_T0_OUT = (int16_t)calib_raw[6] + ((int16_t)calib_raw[7] << 8);
+ calib_info->H1_T0_OUT = (int16_t)calib_raw[10] + ((int16_t)calib_raw[11] << 8);
+ calib_info->T0_OUT = (int16_t)calib_raw[12] + ((int16_t)calib_raw[13] << 8);
+ calib_info->T1_OUT = (int16_t)calib_raw[14] + ((int16_t)calib_raw[15] << 8);
+
+}
+
+ret_code_t hts221_init(hts221_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < HTS221_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ p_instance->ctrl_reg1 = 0;
+ uint8_t send_msg[] = {
+ HTS221_REG_AV_CONF,
+ HTS221_DEF_AV_CONF,
+ 0,
+ 0,
+ 0
+ };
+
+ ret_code_t err = HTS221_WRITE(p_instance, send_msg);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_CALIBRATION | HTS221_INCR_REG_MASK,
+ hts221_init_cb,
+ (uint8_t *) &p_instance->calib_info,
+ HTS221_REG_CALIBRATION_NUM);
+}
+
+ret_code_t hts221_avg_cfg(hts221_instance_t * p_instance,
+ hts221_temp_avg_samples_t temp_avg,
+ hts221_hum_avg_samples_t hum_avg)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = 0;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_AVGT_MASK, HTS221_AVGT_POS, temp_avg);
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_AVGH_MASK, HTS221_AVGH_POS, hum_avg);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_AV_CONF,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_data_rate_cfg(hts221_instance_t * p_instance, hts221_odr_t odr)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg1, HTS221_ODR_MASK, HTS221_ODR_POS, odr);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG1,
+ p_instance->ctrl_reg1
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_pd_enable(hts221_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg1, HTS221_PD_MASK, HTS221_PD_POS, enable);
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG1,
+ p_instance->ctrl_reg1
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+
+
+ret_code_t hts221_boot(hts221_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg2;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_BOOT_MASK, HTS221_BOOT_POS, 1);
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG2,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_heater_enable(hts221_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg2, HTS221_HEATER_MASK, HTS221_HEATER_POS, enable);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG2,
+ p_instance->ctrl_reg2
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_oneshot(hts221_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg2;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_ONE_SHOT_MASK, HTS221_ONE_SHOT_POS, true);
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG2,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_drdy_pin_cfg(hts221_instance_t * p_instance,
+ bool active_low,
+ bool operation,
+ bool drdy_enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = 0;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_DRDY_H_L_MASK, HTS221_DRDY_H_L_POS, active_low);
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_PP_OD_MASK, HTS221_PP_OD_POS, operation);
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_DRDY_EN_MASK, HTS221_DRDY_EN_POS, drdy_enable);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG3,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_temp_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_temp)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_TEMP_OUT_L | HTS221_INCR_REG_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) p_temp,
+ 2);
+}
+
+int16_t hts221_temp_process(hts221_instance_t * p_instance, int16_t raw_temp)
+{
+ ASSERT(p_instance != NULL);
+ int32_t y;
+ int32_t x0 = p_instance->calib_info.T0_OUT;
+ int32_t x1 = p_instance->calib_info.T1_OUT;
+ int32_t y0 = p_instance->calib_info.T0_degC_x8;
+ int32_t y1 = p_instance->calib_info.T1_degC_x8;
+
+ y = ((y0 * (x1 - raw_temp)) + (y1 * (raw_temp - x0))) / (x1 - x0);
+
+ return y;
+}
+
+ret_code_t hts221_hum_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_hum)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_HUM_OUT_L | HTS221_INCR_REG_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) p_hum,
+ 2);
+}
+
+int16_t hts221_hum_process(hts221_instance_t * p_instance, int16_t raw_hum)
+{
+ ASSERT(p_instance != NULL);
+ int32_t y;
+ int32_t x0 = p_instance->calib_info.H0_T0_OUT;
+ int32_t x1 = p_instance->calib_info.H1_T0_OUT;
+ int32_t y0 = p_instance->calib_info.H0_rH_x2;
+ int32_t y1 = p_instance->calib_info.H1_rH_x2;
+
+ y = ((y0 * (x1 - raw_hum)) + (y1 * (raw_hum - x0))) / (x1 - x0);
+
+ return y;
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h
new file mode 100644
index 0000000..c44d86f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.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 HTS221_H
+#define HTS221_H
+
+#include "nrf_twi_sensor.h"
+#include "hts221_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define HTS221_BASE_ADDRESS 0x5FU
+
+// Who am I default value.
+#define HTS221_WHO_AM_I 0xBC
+
+// Minimal TWI Manager queue size needed for sensor.
+#define HTS221_MIN_QUEUE_SIZE 4
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref HTS221_INSTANCE_DEF.
+ * After that it has to be initialized using @ref hts221_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Configuration functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ *
+ * There are designated functions to read status sensor registers e.g. @ref hts221_status_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * uint8_t h_da = NRF_TWI_SENSOR_REG_VAL_GET(status, HTS221_H_DA_MASK, HTS221_H_DA_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+/**
+ * @brief Temperature average setting.
+ */
+
+typedef enum
+{
+ HTS221_TEMP_SAMPLES_2,
+ HTS221_TEMP_SAMPLES_4,
+ HTS221_TEMP_SAMPLES_8,
+ HTS221_TEMP_SAMPLES_16,
+ HTS221_TEMP_SAMPLES_32,
+ HTS221_TEMP_SAMPLES_64,
+ HTS221_TEMP_SAMPLES_128,
+ HTS221_TEMP_SAMPLES_256
+} hts221_temp_avg_samples_t;
+
+/**
+ * @brief Humidity average setting.
+ */
+typedef enum
+{
+ HTS221_HUMIDITY_SAMPLES_4,
+ HTS221_HUMIDITY_SAMPLES_8,
+ HTS221_HUMIDITY_SAMPLES_16,
+ HTS221_HUMIDITY_SAMPLES_32,
+ HTS221_HUMIDITY_SAMPLES_64,
+ HTS221_HUMIDITY_SAMPLES_128,
+ HTS221_HUMIDITY_SAMPLES_256,
+ HTS221_HUMIDITY_SAMPLES_512
+} hts221_hum_avg_samples_t;
+
+/**
+ * @brief Output data rate settings.
+ */
+typedef enum
+{
+ HTS221_ODR_ONESHOT,
+ HTS221_ODR_1HZ,
+ HTS221_ODR_7HZ,
+ HTS221_ODR_12_5HZ,
+} hts221_odr_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Return error code from TWI manager and underlying drivers.
+ * @param[in] p_data Pointer to sensor data.
+ */
+typedef void (* hts221_data_callback_t)(ret_code_t result, int16_t * p_data);
+
+/**
+ * @brief Macro creating hts221 sensor instance.
+ *
+ * @param[in] _hts221_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance. @ref NRF_TWI_SENSOR_DEF
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define HTS221_INSTANCE_DEF(_hts221_inst_name, _p_twi_sensor, _sensor_address) \
+ HTS221_INTERNAL_INSTANCE_DEF(_hts221_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Function initializing hts221 sensor
+ *
+ * Writes configuration from sensor instance into sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance created by macro
+ *
+ * @note TWI manager queue size has to be at least
+ * HTS221_MIN_QUEUE_SIZE element long.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_init(hts221_instance_t * p_instance);
+
+/**
+ * @brief Function for setting average configuration.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] temp_avg Number of temperature average samples.
+ * @param[in] hum_avg Number of humidity average samples.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_avg_cfg(hts221_instance_t * p_instance,
+ hts221_temp_avg_samples_t temp_avg,
+ hts221_hum_avg_samples_t hum_avg);
+
+/**
+ * @brief Function for setting power down mode
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable True if device is powered, false if power down.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_pd_enable(hts221_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for rebooting sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_boot(hts221_instance_t * p_instance);
+
+/**
+ * @brief Function for setting heater.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable True if heater is on.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_heater_enable(hts221_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for setting one shot mode
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable True if one shot mode is on.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_oneshot(hts221_instance_t * p_instance);
+
+/**
+ * @brief Function for setting sensor_data ready output signal.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] active_low True if active low, false if active high.
+ * @param[in] open_drain True if open drain, false if push-pull.
+ * @param[in] drdy_enable True if pin is enabled.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_drdy_pin_cfg(hts221_instance_t * p_instance,
+ bool active_low,
+ bool operation,
+ bool drdy_enable);
+
+/**
+ * @brief Function for setting output data rate.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] odr Desired output data rate.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_data_rate_cfg(hts221_instance_t * p_instance, hts221_odr_t odr);
+
+/**
+ * @brief Function for reading sensors temperature.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_callback Function to be called when sensor data is gathered.
+ * @param[out] p_temp Pointer for raw temperature value, single int16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t hts221_temp_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_temp);
+
+/**
+ * @brief Function for calculating temperature based on sensors calibration data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] raw_temp Raw temperature in.
+ *
+ * @return Temperature * 8
+ */
+int16_t hts221_temp_process(hts221_instance_t * p_instance, int16_t raw_temp);
+
+/**
+ * @brief Function for reading sensors humidity.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_callback Function to be called when data is gathered.
+ * @param[out] p_hum Pointer for raw humidity value, single int16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t hts221_hum_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_hum);
+
+/**
+ * @brief Function for calculating humidity based on sensors calibration data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] raw_hum Raw humidity in.
+ *
+ * @return Humidity * 2
+ */
+int16_t hts221_hum_process(hts221_instance_t * p_instance, int16_t raw_hum);
+
+/**
+ * @brief Function for reading WHO_AM_I register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t hts221_who_am_i_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t hts221_status_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HTS221_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h
new file mode 100644
index 0000000..c4e538f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h
@@ -0,0 +1,235 @@
+/**
+ * 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 HTS221_INTERNAL_H
+#define HTS221_INTERNAL_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief HTS221 sensor registers.
+ */
+#define HTS221_REG_WHO_AM_I 0x0F
+#define HTS221_REG_AV_CONF 0x10
+#define HTS221_REG_CTRL_REG1 0x20
+#define HTS221_REG_CTRL_REG2 0x21
+#define HTS221_REG_CTRL_REG3 0x22
+#define HTS221_REG_STATUS_REG 0x27
+#define HTS221_REG_HUM_OUT_L 0x28
+#define HTS221_REG_HUM_OUT_H 0x29
+#define HTS221_REG_TEMP_OUT_L 0x2A
+#define HTS221_REG_TEMP_OUT_H 0x2B
+
+// Calibration registers
+#define HTS221_REG_CALIBRATION 0x30
+
+#define HTS221_REG_CALIBRATION_NUM 16
+#define HTS221_REG_CTRL_NUM 3
+
+// For auto incrementing address, msb in register address must be set to 1.
+#define HTS221_INCR_REG_MASK 0x80
+
+/**
+ * @brief AV_CONF register bitmasks.
+ */
+#define HTS221_DEF_AV_CONF 0x1B
+
+// Register validity bitmask.
+#define HTS221_AV_CONF_VALID_MASK 0xC0
+
+// Bitmasks for AVGT.
+#define HTS221_AVGT_POS 3
+#define HTS221_AVGT_MASK (7 << HTS221_AVGT_POS)
+
+// Bitmasks for AVGH.
+#define HTS221_AVGH_POS 0
+#define HTS221_AVGH_MASK (7 << HTS221_AVGH_POS)
+
+
+/**
+ * @brief Control register 1 bitmasks.
+ */
+
+// Register validity bitmask.
+#define HTS221_CTRL1_VALID_MASK 0x78
+
+// Bitmasks for PD.
+#define HTS221_PD_POS 7
+#define HTS221_PD_MASK (1 << HTS221_PD_POS)
+
+// Bitmasks for BDU.
+#define HTS221_BDU_POS 2
+#define HTS221_BDU_MASK (1 << HTS221_BDU_POS)
+
+// Bitmasks for ODR.
+#define HTS221_ODR_POS 0
+#define HTS221_ODR_MASK (3 << HTS221_ODR_POS)
+
+
+/**
+ * @brief Control register 2 bitmasks.
+ */
+
+// Register validity bitmask.
+#define HTS221_CTRL2_VALID_MASK 0x7C
+
+// Bitmasks for BOOT.
+#define HTS221_BOOT_POS 7
+#define HTS221_BOOT_MASK (1 << HTS221_BOOT_POS)
+
+// Bitmasks for Heater.
+#define HTS221_HEATER_POS 1
+#define HTS221_HEATER_MASK (1 << HTS221_HEATER_POS)
+
+// Bitmasks for ONE_SHOT.
+#define HTS221_ONE_SHOT_POS 0
+#define HTS221_ONE_SHOT_MASK (1 << HTS221_ONE_SHOT_POS)
+
+
+/**
+ * @brief Control register 3 bitmasks.
+ */
+
+// Register validity bitmask.
+#define HTS221_CTRL3_VALID_MASK 0x3B
+
+// Bitmasks for DRDY_H_L.
+#define HTS221_DRDY_H_L_POS 7
+#define HTS221_DRDY_H_L_MASK (1 << HTS221_DRDY_H_L_POS)
+
+// Bitmasks for PP_OD
+#define HTS221_PP_OD_POS 6
+#define HTS221_PP_OD_MASK (1 << HTS221_PP_OD_POS)
+
+// Bitmasks for DRDY_EN.
+#define HTS221_DRDY_EN_POS 2
+#define HTS221_DRDY_EN_MASK (1 << HTS221_DRDY_EN_POS)
+
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for H_DA.
+#define HTS221_H_DA_POS 1
+#define HTS221_H_DA_MASK (1 << HTS221_H_DA_POS)
+
+// Bitmasks for T_DA
+#define HTS221_T_DA_POS 0
+#define HTS221_T_DA_MASK (1 << HTS221_T_DA_POS)
+
+
+/**
+ * @brief Structure holding calibration information.
+ */
+typedef struct
+{
+ uint8_t H0_rH_x2;
+ uint8_t H1_rH_x2;
+ uint16_t T0_degC_x8;
+ uint16_t T1_degC_x8;
+ int16_t H0_T0_OUT;
+ int16_t H1_T0_OUT;
+ int16_t T0_OUT;
+ int16_t T1_OUT;
+ uint16_t padding; //<- Additional memory needed to store all calibration registers.
+} hts221_calib_t;
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+
+ hts221_calib_t calib_info;
+ uint8_t ctrl_reg1;
+ uint8_t ctrl_reg2;
+
+} hts221_instance_t;
+
+/**
+ * @brief Macro creating hts221 sensor instance.
+ */
+#define HTS221_INTERNAL_INSTANCE_DEF(_hts221_inst_name, _p_twi_sensor, _sensor_address) \
+ static hts221_instance_t _hts221_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address, \
+ }
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t hts221_who_am_i_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_WHO_AM_I,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t hts221_status_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_STATUS_REG,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HTS221_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c
new file mode 100644
index 0000000..f61a87d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c
@@ -0,0 +1,401 @@
+/**
+ * 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(ILI9341)
+
+#include "nrf_lcd.h"
+#include "nrf_drv_spi.h"
+#include "nrf_delay.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+
+// Set of commands described in ILI9341 datasheet.
+#define ILI9341_NOP 0x00
+#define ILI9341_SWRESET 0x01
+#define ILI9341_RDDID 0x04
+#define ILI9341_RDDST 0x09
+
+#define ILI9341_SLPIN 0x10
+#define ILI9341_SLPOUT 0x11
+#define ILI9341_PTLON 0x12
+#define ILI9341_NORON 0x13
+
+#define ILI9341_RDMODE 0x0A
+#define ILI9341_RDMADCTL 0x0B
+#define ILI9341_RDPIXFMT 0x0C
+#define ILI9341_RDIMGFMT 0x0D
+#define ILI9341_RDSELFDIAG 0x0F
+
+#define ILI9341_INVOFF 0x20
+#define ILI9341_INVON 0x21
+#define ILI9341_GAMMASET 0x26
+#define ILI9341_DISPOFF 0x28
+#define ILI9341_DISPON 0x29
+
+#define ILI9341_CASET 0x2A
+#define ILI9341_PASET 0x2B
+#define ILI9341_RAMWR 0x2C
+#define ILI9341_RAMRD 0x2E
+
+#define ILI9341_PTLAR 0x30
+#define ILI9341_MADCTL 0x36
+#define ILI9341_PIXFMT 0x3A
+
+#define ILI9341_FRMCTR1 0xB1
+#define ILI9341_FRMCTR2 0xB2
+#define ILI9341_FRMCTR3 0xB3
+#define ILI9341_INVCTR 0xB4
+#define ILI9341_DFUNCTR 0xB6
+
+#define ILI9341_PWCTR1 0xC0
+#define ILI9341_PWCTR2 0xC1
+#define ILI9341_PWCTR3 0xC2
+#define ILI9341_PWCTR4 0xC3
+#define ILI9341_PWCTR5 0xC4
+#define ILI9341_VMCTR1 0xC5
+#define ILI9341_VMCTR2 0xC7
+#define ILI9341_PWCTRSEQ 0xCB
+#define ILI9341_PWCTRA 0xCD
+#define ILI9341_PWCTRB 0xCF
+
+#define ILI9341_RDID1 0xDA
+#define ILI9341_RDID2 0xDB
+#define ILI9341_RDID3 0xDC
+#define ILI9341_RDID4 0xDD
+
+#define ILI9341_GMCTRP1 0xE0
+#define ILI9341_GMCTRN1 0xE1
+#define ILI9341_DGMCTR1 0xE2
+#define ILI9341_DGMCTR2 0xE3
+#define ILI9341_TIMCTRA 0xE8
+#define ILI9341_TIMCTRB 0xEA
+
+#define ILI9341_ENGMCTR 0xF2
+#define ILI9341_INCTR 0xF6
+#define ILI9341_PUMP 0xF7
+
+#define ILI9341_MADCTL_MY 0x80
+#define ILI9341_MADCTL_MX 0x40
+#define ILI9341_MADCTL_MV 0x20
+#define ILI9341_MADCTL_ML 0x10
+#define ILI9341_MADCTL_RGB 0x00
+#define ILI9341_MADCTL_BGR 0x08
+#define ILI9341_MADCTL_MH 0x04
+
+static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ILI9341_SPI_INSTANCE);
+
+static inline void spi_write(const void * data, size_t size)
+{
+ APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0));
+}
+
+static inline void write_command(uint8_t c)
+{
+ nrf_gpio_pin_clear(ILI9341_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static inline void write_data(uint8_t c)
+{
+ nrf_gpio_pin_set(ILI9341_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static void set_addr_window(uint16_t x_0, uint16_t y_0, uint16_t x_1, uint16_t y_1)
+{
+ ASSERT(x_0 <= x_1);
+ ASSERT(y_0 <= y_1);
+
+ write_command(ILI9341_CASET);
+ write_data(x_0 >> 8);
+ write_data(x_0);
+ write_data(x_1 >> 8);
+ write_data(x_1);
+ write_command(ILI9341_PASET);
+ write_data(y_0 >> 8);
+ write_data(y_0);
+ write_data(y_1 >> 8);
+ write_data(y_1);
+ write_command(ILI9341_RAMWR);
+}
+
+static void command_list(void)
+{
+ write_command(ILI9341_SWRESET);
+ nrf_delay_ms(120);
+ write_command(ILI9341_DISPOFF);
+ nrf_delay_ms(120);
+ write_command(ILI9341_PWCTRB);
+ write_data(0x00);
+ write_data(0XC1);
+ write_data(0X30);
+
+ write_command(ILI9341_TIMCTRA);
+ write_data(0x85);
+ write_data(0x00);
+ write_data(0x78);
+
+ write_command(ILI9341_PWCTRSEQ);
+ write_data(0x39);
+ write_data(0x2C);
+ write_data(0x00);
+ write_data(0x34);
+ write_data(0x02);
+
+ write_command(ILI9341_PUMP);
+ write_data(0x20);
+
+ write_command(ILI9341_TIMCTRB);
+ write_data(0x00);
+ write_data(0x00);
+
+ write_command(ILI9341_PWCTR1);
+ write_data(0x23);
+
+ write_command(ILI9341_PWCTR2);
+ write_data(0x10);
+
+ write_command(ILI9341_VMCTR1);
+ write_data(0x3e);
+ write_data(0x28);
+
+ write_command(ILI9341_VMCTR2);
+ write_data(0x86);
+
+ write_command(ILI9341_MADCTL);
+ write_data(0x48);
+
+ write_command(ILI9341_PIXFMT);
+ write_data(0x55);
+
+ write_command(ILI9341_FRMCTR1);
+ write_data(0x00);
+ write_data(0x18);
+
+ write_command(ILI9341_DFUNCTR);
+ write_data(0x08);
+ write_data(0x82);
+ write_data(0x27);
+
+ write_command(ILI9341_ENGMCTR);
+ write_data(0x00);
+
+ write_command(ILI9341_GAMMASET);
+ write_data(0x01);
+
+ write_command(ILI9341_GMCTRP1);
+ write_data(0x0F);
+ write_data(0x31);
+ write_data(0x2B);
+ write_data(0x0C);
+ write_data(0x0E);
+ write_data(0x08);
+ write_data(0x4E);
+ write_data(0xF1);
+ write_data(0x37);
+ write_data(0x07);
+ write_data(0x10);
+ write_data(0x03);
+ write_data(0x0E);
+ write_data(0x09);
+ write_data(0x00);
+
+ write_command(ILI9341_GMCTRN1);
+ write_data(0x00);
+ write_data(0x0E);
+ write_data(0x14);
+ write_data(0x03);
+ write_data(0x11);
+ write_data(0x07);
+ write_data(0x31);
+ write_data(0xC1);
+ write_data(0x48);
+ write_data(0x08);
+ write_data(0x0F);
+ write_data(0x0C);
+ write_data(0x31);
+ write_data(0x36);
+ write_data(0x0F);
+
+ write_command(ILI9341_SLPOUT);
+ nrf_delay_ms(120);
+ write_command(ILI9341_DISPON);
+}
+
+static ret_code_t hardware_init(void)
+{
+ ret_code_t err_code;
+
+ nrf_gpio_cfg_output(ILI9341_DC_PIN);
+
+ nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
+
+ spi_config.sck_pin = ILI9341_SCK_PIN;
+ spi_config.miso_pin = ILI9341_MISO_PIN;
+ spi_config.mosi_pin = ILI9341_MOSI_PIN;
+ spi_config.ss_pin = ILI9341_SS_PIN;
+
+ err_code = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL);
+ return err_code;
+}
+
+static ret_code_t ili9341_init(void)
+{
+ ret_code_t err_code;
+
+ err_code = hardware_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ command_list();
+
+ return err_code;
+}
+
+static void ili9341_uninit(void)
+{
+ nrf_drv_spi_uninit(&spi);
+}
+
+static void ili9341_pixel_draw(uint16_t x, uint16_t y, uint32_t color)
+{
+ set_addr_window(x, y, x, y);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ILI9341_DC_PIN);
+
+ spi_write(data, sizeof(data));
+
+ nrf_gpio_pin_clear(ILI9341_DC_PIN);
+}
+
+static void ili9341_rect_draw(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color)
+{
+ set_addr_window(x, y, x + width - 1, y + height - 1);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ILI9341_DC_PIN);
+
+ // Duff's device algorithm for optimizing loop.
+ uint32_t i = (height * width + 7) / 8;
+
+/*lint -save -e525 -e616 -e646 */
+ switch ((height * width) % 8) {
+ case 0:
+ do {
+ spi_write(data, sizeof(data));
+ case 7:
+ spi_write(data, sizeof(data));
+ case 6:
+ spi_write(data, sizeof(data));
+ case 5:
+ spi_write(data, sizeof(data));
+ case 4:
+ spi_write(data, sizeof(data));
+ case 3:
+ spi_write(data, sizeof(data));
+ case 2:
+ spi_write(data, sizeof(data));
+ case 1:
+ spi_write(data, sizeof(data));
+ } while (--i > 0);
+ default:
+ break;
+ }
+/*lint -restore */
+
+ nrf_gpio_pin_clear(ILI9341_DC_PIN);
+}
+
+static void ili9341_dummy_display(void)
+{
+ /* No implementation needed. */
+}
+
+static void ili9341_rotation_set(nrf_lcd_rotation_t rotation)
+{
+ write_command(ILI9341_MADCTL);
+ switch (rotation) {
+ case NRF_LCD_ROTATE_0:
+ write_data(ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR);
+ break;
+ case NRF_LCD_ROTATE_90:
+ write_data(ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR);
+ break;
+ case NRF_LCD_ROTATE_180:
+ write_data(ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR);
+ break;
+ case NRF_LCD_ROTATE_270:
+ write_data(ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR);
+ break;
+ default:
+ break;
+ }
+}
+
+static void ili9341_display_invert(bool invert)
+{
+ write_command(invert ? ILI9341_INVON : ILI9341_INVOFF);
+}
+
+static lcd_cb_t ili9341_cb = {
+ .height = ILI9341_HEIGHT,
+ .width = ILI9341_WIDTH
+};
+
+
+const nrf_lcd_t nrf_lcd_ili9341 = {
+ .lcd_init = ili9341_init,
+ .lcd_uninit = ili9341_uninit,
+ .lcd_pixel_draw = ili9341_pixel_draw,
+ .lcd_rect_draw = ili9341_rect_draw,
+ .lcd_display = ili9341_dummy_display,
+ .lcd_rotation_set = ili9341_rotation_set,
+ .lcd_display_invert = ili9341_display_invert,
+ .p_lcd_cb = &ili9341_cb
+};
+
+#endif // NRF_MODULE_ENABLED(ILI9341)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c
new file mode 100644
index 0000000..77b43b0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c
@@ -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.
+ *
+ */
+
+#include "lis2dh12.h"
+
+#define RETURN_IF_ERR(err) \
+ if (err != NRF_SUCCESS) \
+ { \
+ return err; \
+ }
+
+ret_code_t lis2dh12_init(lis2dh12_instance_t * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ memset(&p_inst->temp_cfg, 0, &p_inst->act_dur - &p_inst->temp_cfg);
+ p_inst->ctrl0 = LIS2DH12_CTRL_REG0_VALID_SET;
+ p_inst->ctrl1 = 0x07;
+ p_inst->ctrl4 = 0x80;
+
+ return lis2dh12_cfg_commit(p_inst);
+}
+
+ret_code_t lis2dh12_cfg_commit(lis2dh12_instance_t * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ ret_code_t err;
+ p_inst->ctrl0 &= ~LIS2DH12_CTRL_REG0_VALID_MASK;
+ p_inst->ctrl0 |= LIS2DH12_CTRL_REG0_VALID_SET;
+
+ uint8_t ctrl_msg[] = {
+ LIS2DH12_REG_CTRL_REG0 | LIS2DH12_AUTO_INCR_MASK,
+ p_inst->ctrl0,
+ p_inst->temp_cfg,
+ p_inst->ctrl1,
+ p_inst->ctrl2,
+ p_inst->ctrl3,
+ p_inst->ctrl4,
+ p_inst->ctrl5,
+ p_inst->ctrl6,
+ p_inst->reference
+ };
+ err = nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ ctrl_msg,
+ ARRAY_SIZE(ctrl_msg),
+ true);
+ RETURN_IF_ERR(err);
+ uint8_t fifo_msg[] = {
+ LIS2DH12_REG_FIFO_CTRL | LIS2DH12_AUTO_INCR_MASK,
+ p_inst->fifo_ctrl,
+ 0,
+ p_inst->int1_cfg,
+ 0,
+ p_inst->int1_ths,
+ p_inst->int1_dur,
+ p_inst->int2_cfg,
+ 0,
+ p_inst->int2_ths,
+ p_inst->int2_dur,
+ p_inst->click_cfg
+ };
+ err = nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ fifo_msg,
+ ARRAY_SIZE(fifo_msg),
+ true);
+ RETURN_IF_ERR(err);
+
+ uint8_t time_msg[] = {
+ LIS2DH12_REG_CLICK_THS | LIS2DH12_AUTO_INCR_MASK,
+ p_inst->click_ths,
+ p_inst->time_lim,
+ p_inst->latency,
+ p_inst->time_win,
+ p_inst->act_ths,
+ p_inst->act_dur
+ };
+ err = nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ time_msg,
+ ARRAY_SIZE(time_msg),
+ true);
+ return err;
+}
+
+ret_code_t lis2dh12_data_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_data_cb_t user_cb,
+ lis2dh12_data_t * p_data,
+ uint8_t samples)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_OUT_X_L | LIS2DH12_AUTO_INCR_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_cb,
+ (uint8_t *) p_data,
+ samples * LIS2DH12_BYTES_PER_SAMPLE);
+}
+
+ret_code_t lis2dh12_temp_enable(lis2dh12_instance_t * p_inst, bool temp_en)
+{
+ ASSERT(p_inst != NULL);
+ if (temp_en == true)
+ {
+ NRF_TWI_SENSOR_REG_SET(p_inst->temp_cfg, LIS2DH12_TEMP_EN_MASK, LIS2DH12_TEMP_EN_POS, 3);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(p_inst->temp_cfg, LIS2DH12_TEMP_EN_MASK, LIS2DH12_TEMP_EN_POS, 0);
+ }
+
+ uint8_t send_msg[] = {
+ LIS2DH12_REG_TEMP_CFG_REG,
+ p_inst->temp_cfg
+ };
+
+ return nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+}
+
+ret_code_t lis2dh12_temp_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_temp_cb_t user_cb,
+ int16_t * p_temp)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_OUT_TEMP_L | LIS2DH12_AUTO_INCR_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_cb,
+ (uint8_t *) p_temp,
+ LIS2DH12_BYTES_PER_TEMP);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h
new file mode 100644
index 0000000..13dd0ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h
@@ -0,0 +1,491 @@
+/**
+ * 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 LIS2DH12_H
+#define LIS2DH12_H
+
+#include "nrf_twi_sensor.h"
+#include "lis2dh12_internal.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define LIS2DH12_BASE_ADDRESS_LOW 0x18U
+#define LIS2DH12_BASE_ADDRESS_HIGH 0x19U
+
+// WHO_AM_I register value.
+#define LIS2DH12_WHO_AM_I 0x33
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref LIS2DH12_INSTANCE DEF.
+ * After that it has to be initialized using @ref lis2dh12_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Sensor settings are modified using asynchronous macros, using them does not change
+ * real sensor settings until @ref lis2dh12_cfg_commit is called.
+ * Example:
+ * LIS2DH12_DATA_CFG(m_sensor, LIS2DH12_ODR_200HZ, false, true, true, true, LIS2DH12_SCALE_2G, 1);
+ * lis2dh12_cfg_commit(&m_sensor);
+ *
+ * There are designated functions to read status sensor registers e.g. @ref lis2dh12_status_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro. For specific bitmasks, check lis2dh12_internal.h
+ * Example:
+ * bool zyxor = NRF_TWI_SENSOR_REG_VAL_GET(status_reg, LIS2DH12_ZYXOR_MASK, LIS2DH12_ZYXOR_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+/**
+ * @brief Output data rate settings.
+ */
+typedef enum
+{
+ LIS2DH12_ODR_POWERDOWN,
+ LIS2DH12_ODR_1HZ,
+ LIS2DH12_ODR_10HZ,
+ LIS2DH12_ODR_25HZ,
+ LIS2DH12_ODR_50HZ,
+ LIS2DH12_ODR_100HZ,
+ LIS2DH12_ODR_200HZ,
+ LIS2DH12_ODR_400HZ,
+ LIS2DH12_ODR_1620HZ,
+ LIS2DH12_ODR_1344_5376HZ
+} lis2dh12_odr_t;
+
+/**
+ * @brief Fifo mode settings.
+ */
+typedef enum
+{
+ LIS2DH12_BYPASS,
+ LIS2DH12_FIFO,
+ LIS2DH12_STREAM,
+ LIS2DH12_STREAM_TO_FIFO
+} lis2dh12_fifo_mode_t;
+
+/**
+ * @brief Filter mode setting.
+ */
+typedef enum
+{
+ LIS2DH12_FILTER_MODE_NORMAL_W_RESET,
+ LIS2DH12_FILTER_MODE_REFERENCE,
+ LIS2DH12_FILTER_MODE_NORMAL,
+ LIS2DH12_FILTER_MODE_AUTO_RESET
+} lis2dh12_filter_mode_t;
+
+/**
+ * @brief Filter frequency setting.
+ */
+typedef enum
+{
+ LIS2DH12_FILTER_FREQ_1,
+ LIS2DH12_FILTER_FREQ_2,
+ LIS2DH12_FILTER_FREQ_3,
+ LIS2DH12_FILTER_FREQ_4
+} lis2dh12_filter_freq_t;
+
+/**
+ * @brief Accelerometer scale setting.
+ */
+typedef enum
+{
+ LIS2DH12_SCALE_2G,
+ LIS2DH12_SCALE_4G,
+ LIS2DH12_SCALE_8G,
+ LIS2DH12_SCALE_16G
+} lis2dh12_scale_t;
+
+/**
+ * @brief Structure containing accelerometer data.
+ */
+typedef struct
+{
+ int16_t x;
+ int16_t y;
+ int16_t z;
+} lis2dh12_data_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_data Pointer to raw sensor data structure.
+ */
+typedef void (* lis2dh12_data_cb_t)(ret_code_t result, lis2dh12_data_t * p_data);
+
+/**
+ * @brief Temperature callback prototype.
+ *
+ * @param[in] result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_temp Temperature value.
+ */
+typedef void (* lis2dh12_temp_cb_t)(ret_code_t result, int16_t * p_temp);
+
+/**
+ * @brief Macro for defining sensor instance.
+ *
+ * @param[in] _lis2dh12_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance.
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define LIS2DH12_INSTANCE_DEF(_lis2dh12_inst_name, _p_twi_sensor, _sensor_address) \
+ LIS2DH12_INTERNAL_INSTANCE_DEF(_lis2dh12_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Macro for setting data acquisition configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _odr Data rate. @ref lis2dh12_odr_t
+ * @param[in] _lp Power mode. True if low power mode is enabled.
+ * @param[in] _z_en Enable measure in z-axis. True if enabled.
+ * @param[in] _y_en Enable measure in y-axis. True if enabled.
+ * @param[in] _x_en Enable measure in x-axis. True if enabled.
+ * @param[in] _scale Measurement scale. @ref lis2dh12_scale_t
+ * @param[in] _high_res High resolution mode. True if enabled.
+ * Low power can't be enabled when in high resolution mode.
+ */
+#define LIS2DH12_DATA_CFG(_s, _odr, _lp, _z_en, _y_en, _x_en, _scale, _high_res) \
+ LIS2DH12_INTERNAL_DATA_CFG(_s, _odr, _lp, _z_en, _y_en, _x_en, _scale, _high_res)
+
+/**
+ * @brief Function for setting filter configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _mode Filter mode. @ref lis2dh12_filter_mode_t
+ * @param[in] _freq Filter frequency. @ref lis2dh12_filter_freq_t
+ * @param[in] _d_en Enable filter for data acquisition.
+ * @param[in] _c_en Enable filter for click interrupt.
+ * @param[in] _i1_en Enable filter for interrupt 1 aoi.
+ * @param[in] _i2_en Enable filter for interrupt 2 aoi.
+ */
+#define LIS2DH12_FILTER_CFG(_s, _mode, _freq, _d_en, _c_en, _i1_en, _i2_en) \
+ LIS2DH12_INTERNAL_FILTER_CFG(_s, _mode, _freq, _d_en, _c_en, _i1_en, _i2_en)
+
+/**
+ * @brief Macro for configuring INT1 pin.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _cl Enable CLICK interrupt on pin.
+ * @param[in] _ia1 Enable IA1 interrupt on pin.
+ * @param[in] _ia2 Enable IA2 interrupt on pin.
+ * @param[in] _zyxda Enable ZYXDA interrupt on pin.
+ * @param[in] _wtm Enable FIFO watermark interrupt on pin.
+ * @param[in] _ovr Enable FIFO overrun interrupt on pin.
+ * @param[in] _pol Pin active state. Affects also int2 pin.
+ * @arg true Pin is active low.
+ * @arg false Pin is active high
+ * @param[in] _d4d Enable 4D detection on INT1 pin when 6D is enabled on interrupt 1.
+ */
+#define LIS2DH12_INT1_PIN_CFG(_s, _cl, _ia1, _ia2, _zyxda, _wtm, _ovr, _pol, _d4d) \
+ LIS2DH12_INTERNAL_INT1_PIN_CFG(_s, _cl, _ia1, _ia2, _zyxda, _wtm, _ovr, _pol, _d4d)
+
+/**
+ * @brief Macro for configuring INT2 pin.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _cl Enable CLICK interrupt on pin.
+ * @param[in] _ia1 Enable IA1 interrupt on pin.
+ * @param[in] _ia2 Enable IA2 interrupt on pin.
+ * @param[in] _boot Enable boot on pin.
+ * @param[in] _avt Enable activity interrupt on pin.
+ * @param[in] _pol Pin active state. Affects also int1 pin.
+ * @arg true Pin is active low.
+ * @arg false Pin is active high
+ * @param[in] _d4d Enable 4D detection on INT2 pin when 6D is enabled on interrupt 2.
+ */
+#define LIS2DH12_INT2_PIN_CFG(_s, _cl, _ia1, _ia2, _boot, _act, _pol, _d4d) \
+ LIS2DH12_INTERNAL_INT2_PIN_CFG(_s, _cl, _ia1, _ia2, _boot, _act, _pol, _d4d)
+
+ /**
+ * @brief Macro for configuring interrupt 1.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _thr Interrupt threshold.
+ * @param[in] _dur Interrupt duration.
+ * @param[in] _aoi And/Or combination of interrupt events. True if and.
+ * @param[in] _6d 6-direction detection enable. True if enabled.
+ * @param[in] _zh Enable interrupt on Z high event or direction recognition.
+ * @param[in] _zl Enable interrupt on Z low event or direction recognition.
+ * @param[in] _yh Enable interrupt on Y high event or direction recognition.
+ * @param[in] _yl Enable interrupt on Y low event or direction recognition.
+ * @param[in] _xh Enable interrupt on X high event or direction recognition.
+ * @param[in] _xl Enable interrupt on X low event or direction recognition.
+ * @param[in] _lir Latch interrupt 1 request. True if enabled.
+ */
+#define LIS2DH12_INT1_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ LIS2DH12_INTERNAL_INT1_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir)
+
+/**
+ * @brief Macro for configuring interrupt 2.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _thr Interrupt threshold.
+ * @param[in] _dur Interrupt duration.
+ * @param[in] _aoi And/Or combination of interrupt events. True if and.
+ * @param[in] _6d 6-direction detection enable. True if enabled.
+ * @param[in] _zh Enable interrupt on Z high event or direction recognition.
+ * @param[in] _zl Enable interrupt on Z low event or direction recognition.
+ * @param[in] _yh Enable interrupt on Y high event or direction recognition.
+ * @param[in] _yl Enable interrupt on Y low event or direction recognition.
+ * @param[in] _xh Enable interrupt on X high event or direction recognition.
+ * @param[in] _xl Enable interrupt on X low event or direction recognition.
+ * @param[in] _lir Latch interrupt 1 request. True if enabled.
+ */
+#define LIS2DH12_INT2_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ LIS2DH12_INTERNAL_INT2_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir)
+
+/**
+ * @brief Function for setting click configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _zd Enable interrupt double-click on Z-axis.
+ * @param[in] _zs Enable interrupt single-click on Z-axis.
+ * @param[in] _yd Enable interrupt double-click on Y-axis.
+ * @param[in] _ys Enable interrupt single-click on Y-axis.
+ * @param[in] _xd Enable interrupt double-click on X-axis.
+ * @param[in] _xs Enable interrupt single-click on X-axis.
+ * @param[in] _lir Keep high until CLICK_SRC is read.
+ * @arg true Interrupt is kept high until CLICK_SRC is read.
+ * @arg false Interrupt is kept high for the duration of latency window.
+ * @param[in] _ths Click threshold.
+ * @param[in] _lim Click time limit.
+ * @param[in] _ltc Click time latency.
+ * @param[in] _win Click time window.
+ */
+#define LIS2DH12_CLICK_CFG(_s, _zd, _zs, _yd, _ys, _xd, _xs, _lir, _ths, _lim, _ltc, _win) \
+ LIS2DH12_INTERNAL_CLICK_CFG(_s, _zd, _zs, _yd, _ys, _xd, _xs, _lir, _ths, _lim, _ltc, _win)
+
+ /**
+ * @brief Macro for setting sleep configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _ths Sleep-to-wake, return-to-sleep activation threshold in low-power mode.
+ * @param[in] _dur Sleep-to-wake, return-to-sleep duration.
+ */
+#define LIS2DH12_SLEEP_CFG(_s, _ths, _dur) \
+ LIS2DH12_INTERNAL_SLEEP_CFG(_s, _ths, _dur)
+
+/**
+ * @brief Macro for setting reference value for interrupt generation.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _ref Reference value.
+ */
+#define LIS2DH_REF_SET(_s, _ref) \
+ LIS2DH_INTERNAL_REF_SET(_s, _ref)
+
+/**
+ * @brief Macro for setting FIFO configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _en Enables FIFO. True if enabled. False clears FIFO setting.
+ * @param[in] _mode FIFO mode. @ref lis2dh12_fifo_mode_t
+ * @param[in] _t_sel Trigger event pin selection. True if int2 pin, false if int1 pin.
+ * @param[in] _t_thr Trigger threshold.
+ */
+#define LIS2DH12_FIFO_CFG(_s, _en, _mode, _t_sel, _t_thr) \
+ LIS2DH12_INTERNAL_FIFO_CFG(_s, _en, _mode, _t_sel, _t_thr)
+
+/**
+ * @brief Function for initializing LIS2DH12 instance.
+ *
+ * @param[in] p_inst Pointer to sensor instance defined by macro. @ref LIS2DH12_INSTANCE_DEF
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lis2dh12_init(lis2dh12_instance_t * p_inst);
+
+/**
+ * @brief Function for writing configuration to sensor.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lis2dh12_cfg_commit(lis2dh12_instance_t * p_inst);
+
+/**
+ * @brief Function for reading accelerometer data.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after data read is complete.
+ * @param[in] p_data Pointer to data structure.
+ * @param[in] samples Number of samples to read.
+ *
+ * @note When trying to read more than one sample and FIFO is disabled,
+ * current output value will be copied to all read samples.
+ * When trying to read more samples than there is currently in FIFO,
+ * excess samples will be equal to 0.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t lis2dh12_data_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_data_cb_t user_cb,
+ lis2dh12_data_t * p_data,
+ uint8_t samples);
+
+/**
+ * @brief Function for enabling temperature measurement.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] temp_en Temperature measure enable. True if enabled.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lis2dh12_temp_enable(lis2dh12_instance_t * p_inst, bool temp_en);
+
+/**
+ * @brief Function for reading temperature data.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after temperature read is complete.
+ * @param[in] p_temp Temperature value. Pointer to single int16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t lis2dh12_temp_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_temp_cb_t user_cb,
+ int16_t * p_temp);
+
+/**
+ * @brief Function for reading temperature status register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_temp_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading WHO_AM_I register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_who_am_i_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading FIFO source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_fifo_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading interrupt 1 source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_int1_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading interrupt 2 source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_int2_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading click source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_click_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIS2DH12_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h
new file mode 100644
index 0000000..f7b30cf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h
@@ -0,0 +1,823 @@
+/**
+ * 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 LIS2DH12_INTERNAL_H
+#define LIS2DH12_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define LIS2DH12_AUTO_INCR_MASK 0x80
+/**
+ * @brief LIS2DH12 sensor registers.
+ */
+#define LIS2DH12_REG_STATUS_AUX 0x07
+#define LIS2DH12_REG_OUT_TEMP_L 0x0C
+#define LIS2DH12_REG_OUT_TEMP_H 0x0D
+#define LIS2DH12_REG_WHO_AM_I 0x0F
+#define LIS2DH12_REG_CTRL_REG0 0x1E
+#define LIS2DH12_REG_TEMP_CFG_REG 0x1F
+#define LIS2DH12_REG_CTRL_REG1 0x20
+#define LIS2DH12_REG_CTRL_REG2 0x21
+#define LIS2DH12_REG_CTRL_REG3 0x22
+#define LIS2DH12_REG_CTRL_REG4 0x23
+#define LIS2DH12_REG_CTRL_REG5 0x24
+#define LIS2DH12_REG_CTRL_REG6 0x25
+#define LIS2DH12_REG_REFERENCE 0x26
+#define LIS2DH12_REG_STATUS 0x27
+#define LIS2DH12_REG_OUT_X_L 0x28
+#define LIS2DH12_REG_OUT_X_H 0x29
+#define LIS2DH12_REG_OUT_Y_L 0x2A
+#define LIS2DH12_REG_OUT_Y_H 0x2B
+#define LIS2DH12_REG_OUT_Z_L 0x2C
+#define LIS2DH12_REG_OUT_Z_H 0x2D
+#define LIS2DH12_REG_FIFO_CTRL 0x2E
+#define LIS2DH12_REG_FIFO_SRC 0x2F
+#define LIS2DH12_REG_INT1_CFG 0x30
+#define LIS2DH12_REG_INT1_SRC 0x31
+#define LIS2DH12_REG_INT1_THS 0x32
+#define LIS2DH12_REG_INT1_DURATION 0x33
+#define LIS2DH12_REG_INT2_CFG 0x34
+#define LIS2DH12_REG_INT2_SRC 0x35
+#define LIS2DH12_REG_INT2_THS 0x36
+#define LIS2DH12_REG_INT2_DURATION 0x37
+#define LIS2DH12_REG_CLICK_CFG 0x38
+#define LIS2DH12_REG_CLICK_SRC 0x39
+#define LIS2DH12_REG_CLICK_THS 0x3A
+#define LIS2DH12_REG_TIME_LIMIT 0x3B
+#define LIS2DH12_REG_TIME_LATENCY 0x3C
+#define LIS2DH12_REG_TIME_WINDOW 0x3D
+#define LIS2DH12_REG_ACT_THS 0x3E
+#define LIS2DH12_REG_ACT_DUR 0x3F
+
+
+/**
+ * @brief Config register defaults.
+ */
+#define LIS2DH12_DEF_CTRL_REG0 0x10
+#define LIS2DH12_DEF_CTRL_REG1 0x07
+
+#define LIS2DH12_BYTES_PER_SAMPLE 6
+#define LIS2DH12_BYTES_PER_TEMP 2
+
+/**
+ * @brief Status reg aux bitmasks.
+ */
+
+// Bitmasks for TOR.
+#define LIS2DH12_TOR_POS 6
+#define LIS2DH12_TOR_MASK (1 << LIS2DH12_TOR_POS)
+
+// Bitmasks for TDA.
+#define LIS2DH12_TDA_POS 2
+#define LIS2DH12_TDA_MASK (1 << LIS2DH12_TDA_POS)
+
+
+/**
+ * @brief Control register 0 bitmasks
+ */
+#define LIS2DH12_CTRL_REG0_VALID_MASK 0x7F
+#define LIS2DH12_CTRL_REG0_VALID_SET 0x10
+
+// Bitmasks for SDO_PU_DISC.
+#define LIS2DH12_SDO_PU_DISC_POS 7
+#define LIS2DH12_SDO_PU_DISC_MASK (1 << LIS2DH12_SDO_PU_DISC_POS)
+
+
+/**
+ * @brief Temp config register bitmasks
+ */
+#define LIS2DH12_TEMP_CONF_VALID_MASK 0x3F
+
+// Bitmasks for TEMP_EN
+#define LIS2DH12_TEMP_EN_POS 6
+#define LIS2DH12_TEMP_EN_MASK (3 << LIS2DH12_TEMP_EN_POS)
+
+
+/**
+ * @brief Control register 1 bitmasks
+ */
+
+// Bitmasks for ODR.
+#define LIS2DH12_ODR_POS 4
+#define LIS2DH12_ODR_MASK (0x0F << LIS2DH12_ODR_POS)
+
+// Bitmasks for LP_EN
+#define LIS2DH12_LP_EN_POS 3
+#define LIS2DH12_LP_EN_MASK (1 << LIS2DH12_LP_EN_POS)
+
+// Bitmasks for Z_EN
+#define LIS2DH12_Z_EN_POS 2
+#define LIS2DH12_Z_EN_MASK (1 << LIS2DH12_Z_EN_POS)
+
+// Bitmasks for Y_EN
+#define LIS2DH12_Y_EN_POS 1
+#define LIS2DH12_Y_EN_MASK (1 << LIS2DH12_Y_EN_POS)
+
+// Bitmasks for X_EN
+#define LIS2DH12_X_EN_POS 0
+#define LIS2DH12_X_EN_MASK (1 << LIS2DH12_X_EN_POS)
+
+
+/**
+ * @brief Control register 2 bitmasks.
+ */
+
+// Bitmasks for HPM.
+#define LIS2DH12_HPM_POS 6
+#define LIS2DH12_HPM_MASK (3 << LIS2DH12_HPM_POS)
+
+// Bitmasks for HPCF.
+#define LIS2DH12_HPCF_POS 4
+#define LIS2DH12_HPCF_MASK (3 << LIS2DH12_HPCF_POS)
+
+// Bitmasks for FDS.
+#define LIS2DH12_FDS_POS 3
+#define LIS2DH12_FDS_MASK (1 << LIS2DH12_FDS_POS)
+
+// Bitmasks for HPCLICK.
+#define LIS2DH12_HP_C_POS 2
+#define LIS2DH12_HP_C_MASK (1 << LIS2DH12_HP_C_POS)
+
+// Bitmasks for HP_IA2.
+#define LIS2DH12_HP_I2_POS 1
+#define LIS2DH12_HP_I2_MASK (1 << LIS2DH12_HP_I2_POS)
+
+// Bitmasks for HP_IA1.
+#define LIS2DH12_HP_I1_POS 0
+#define LIS2DH12_HP_I1_MASK (1 << LIS2DH12_HP_I1_POS)
+
+
+/**
+ * @brief Control register 3 bitmasks.
+ */
+
+// Bitmasks for I1_CLICK.
+#define LIS2DH12_I1_CLICK_POS 7
+#define LIS2DH12_I1_CLICK_MASK (1 << LIS2DH12_I1_CLICK_POS)
+
+// Bitmasks for I1_IA1.
+#define LIS2DH12_I1_IA1_POS 6
+#define LIS2DH12_I1_IA1_MASK (1 << LIS2DH12_I1_IA1_POS)
+
+// Bitmasks for I1_IA2.
+#define LIS2DH12_I1_IA2_POS 5
+#define LIS2DH12_I1_IA2_MASK (1 << LIS2DH12_I1_IA2_POS)
+
+// Bitmasks for I1_ZYXDA.
+#define LIS2DH12_I1_ZYXDA_POS 4
+#define LIS2DH12_I1_ZYXDA_MASK (1 << LIS2DH12_I1_ZYXDA_POS)
+
+// Bitmasks for I1_WTM.
+#define LIS2DH12_I1_WTM_POS 2
+#define LIS2DH12_I1_WTM_MASK (1 << LIS2DH12_I1_WTM_POS)
+
+// Bitmasks for I1_OVERRUN.
+#define LIS2DH12_I1_OVERRUN_POS 1
+#define LIS2DH12_I1_OVERRUN_MASK (1 << LIS2DH12_I1_OVERRUN_POS)
+
+
+/**
+ * @brief Control register 4 bitmasks.
+ */
+
+// Bitmasks for BDU.
+#define LIS2DH12_BDU_POS 7
+#define LIS2DH12_BDU_MASK (1 << LIS2DH12_BDU_POS)
+
+// Bitmasks for BLE.
+#define LIS2DH12_BLE_POS 6
+#define LIS2DH12_BLE_MASK (1 << LIS2DH12_BLE_POS)
+
+// Bitmasks for FS.
+#define LIS2DH12_FS_POS 4
+#define LIS2DH12_FS_MASK (3 << LIS2DH12_FS_POS)
+
+// Bitmasks for HR.
+#define LIS2DH12_HR_POS 3
+#define LIS2DH12_HR_MASK (1 << LIS2DH12_HR_POS)
+
+// Bitmasks for ST.
+#define LIS2DH12_ST_POS 1
+#define LIS2DH12_ST_MASK (3 << LIS2DH12_ST_POS)
+
+// Bitmasks for SIM.
+#define LIS2DH12_SIM_POS 0
+#define LIS2DH12_SIM_MASK (1 << LIS2DH12_SIM_POS)
+
+
+/**
+ * @brief Control register 5 bitmasks.
+ */
+
+// Bitmasks for BOOT.
+#define LIS2DH12_BOOT_POS 7
+#define LIS2DH12_BOOT_MASK (1 << LIS2DH12_BOOT_POS)
+
+// Bitmasks for FIFO_EN.
+#define LIS2DH12_FIFO_EN_POS 6
+#define LIS2DH12_FIFO_EN_MASK (1 << LIS2DH12_FIFO_EN_POS)
+
+// Bitmasks for LIR_INT1.
+#define LIS2DH12_LIR_INT1_POS 3
+#define LIS2DH12_LIR_INT1_MASK (1 << LIS2DH12_LIR_INT1_POS)
+
+// Bitmasks for D4D_INT1.
+#define LIS2DH12_D4D_INT1_POS 2
+#define LIS2DH12_D4D_INT1_MASK (1 << LIS2DH12_D4D_INT1_POS)
+
+// Bitmasks for LIR_INT2.
+#define LIS2DH12_LIR_INT2_POS 1
+#define LIS2DH12_LIR_INT2_MASK (1 << LIS2DH12_LIR_INT2_POS)
+
+// Bitmasks for D4D_INT2.
+#define LIS2DH12_D4D_INT2_POS 0
+#define LIS2DH12_D4D_INT2_MASK (1 << LIS2DH12_D4D_INT2_POS)
+
+
+/**
+ * @brief Control register 6 bitmasks.
+ */
+
+// Bitmasks for I2_CLICK.
+#define LIS2DH12_I2_CLICK_POS 7
+#define LIS2DH12_I2_CLICK_MASK (1 << LIS2DH12_I2_CLICK_POS)
+
+// Bitmasks for I2_IA1.
+#define LIS2DH12_I2_IA1_POS 6
+#define LIS2DH12_I2_IA1_MASK (1 << LIS2DH12_I2_IA1_POS)
+
+// Bitmasks for I2_IA2.
+#define LIS2DH12_I2_IA2_POS 5
+#define LIS2DH12_I2_IA2_MASK (1 << LIS2DH12_I2_IA2_POS)
+
+// Bitmasks for I2_BOOT.
+#define LIS2DH12_I2_BOOT_POS 4
+#define LIS2DH12_I2_BOOT_MASK (1 << LIS2DH12_I2_BOOT_POS)
+
+// Bitmasks for I2_ACT.
+#define LIS2DH12_I2_ACT_POS 3
+#define LIS2DH12_I2_ACT_MASK (1 << LIS2DH12_I2_ACT_POS)
+
+// Bitmasks for INT_POLARITY.
+#define LIS2DH12_INT_POLARITY_POS 1
+#define LIS2DH12_INT_POLARITY_MASK (1 << LIS2DH12_INT_POLARITY_POS)
+
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for ZYXOR.
+#define LIS2DH12_ZYXOR_POS 7
+#define LIS2DH12_ZYXOR_MASK (1 << LIS2DH12_ZYXOR_POS)
+
+// Bitmasks for ZOR.
+#define LIS2DH12_ZOR_POS 6
+#define LIS2DH12_ZOR_MASK (1 << LIS2DH12_ZOR_POS)
+
+// Bitmasks for YOR.
+#define LIS2DH12_YOR_POS 5
+#define LIS2DH12_YOR_MASK (1 << LIS2DH12_YOR_POS)
+
+// Bitmasks for XOR.
+#define LIS2DH12_XOR_POS 4
+#define LIS2DH12_XOR_MASK (1 << LIS2DH12_XOR_POS)
+
+// Bitmasks for ZYXDA.
+#define LIS2DH12_ZYXDA_POS 3
+#define LIS2DH12_ZYXDA_MASK (1 << LIS2DH12_ZYXDA_POS)
+
+// Bitmasks for ZDA.
+#define LIS2DH12_ZDA_POS 2
+#define LIS2DH12_ZDA_MASK (1 << LIS2DH12_ZDA_POS)
+
+// Bitmasks for YDA.
+#define LIS2DH12_YDA_POS 1
+#define LIS2DH12_YDA_MASK (1 << LIS2DH12_YDA_POS)
+
+// Bitmasks for XDA.
+#define LIS2DH12_XDA_POS 0
+#define LIS2DH12_XDA_MASK (1 << LIS2DH12_XDA_POS)
+/**
+ * @brief FIFO control register bitmasks.
+ */
+
+// Bitmasks for FM.
+#define LIS2DH12_FM_POS 6
+#define LIS2DH12_FM_MASK (3 << LIS2DH12_FM_POS)
+
+// Bitmasks for TR.
+#define LIS2DH12_TR_POS 5
+#define LIS2DH12_TR_MASK (1 << LIS2DH12_TR_POS)
+
+// Bitmasks for FTH.
+#define LIS2DH12_FTH_POS 0
+#define LIS2DH12_FTH_MASK (0x1F << LIS2DH12_FTH_POS)
+
+
+/**
+ * @brief FIFO source register bitmasks.
+ */
+
+// Bitmasks for WTM.
+#define LIS2DH12_WTM_POS 7
+#define LIS2DH12_WTM_MASK (1 << LIS2DH12_WTM_POS)
+
+// Bitmasks for OVRN_FIFO.
+#define LIS2DH12_OVRN_FIFO_POS 6
+#define LIS2DH12_OVRN_FIFO_MASK (1 << LIS2DH12_OVRN_FIFO_POS)
+
+// Bitmasks for EMPTY.
+#define LIS2DH12_EMPTY_POS 5
+#define LIS2DH12_EMPTY_MASK (1 << LIS2DH12_EMPTY_POS)
+
+// Bitmasks for FSS.
+#define LIS2DH12_FSS_POS 0
+#define LIS2DH12_FSS_MASK (0x1F << LIS2DH12_FSS_POS)
+
+
+/**
+ * @brief Interrupt config register bitmasks.
+ */
+
+// Bitmasks for INT_AOI.
+#define LIS2DH12_INT_AOI_POS 7
+#define LIS2DH12_INT_AOI_MASK (1 << LIS2DH12_INT_AOI_POS)
+
+// Bitmasks for INT_6D.
+#define LIS2DH12_INT_6D_POS 6
+#define LIS2DH12_INT_6D_MASK (1 << LIS2DH12_INT_6D_POS)
+
+// Bitmasks for INT_ZHIE.
+#define LIS2DH12_INT_ZHIE_POS 5
+#define LIS2DH12_INT_ZHIE_MASK (1 << LIS2DH12_INT_ZHIE_POS)
+
+// Bitmasks for INT_ZLIE.
+#define LIS2DH12_INT_ZLIE_POS 4
+#define LIS2DH12_INT_ZLIE_MASK (1 << LIS2DH12_INT_ZLIE_POS)
+
+// Bitmasks for INT_YHIE.
+#define LIS2DH12_INT_YHIE_POS 3
+#define LIS2DH12_INT_YHIE_MASK (1 << LIS2DH12_INT_YHIE_POS)
+
+// Bitmasks for INT_YLIE.
+#define LIS2DH12_INT_YLIE_POS 2
+#define LIS2DH12_INT_YLIE_MASK (1 << LIS2DH12_INT_YLIE_POS)
+
+// Bitmasks for INT_XHIE.
+#define LIS2DH12_INT_XHIE_POS 1
+#define LIS2DH12_INT_XHIE_MASK (1 << LIS2DH12_INT_XHIE_POS)
+
+// Bitmasks for INT_XLIE.
+#define LIS2DH12_INT_XLIE_POS 0
+#define LIS2DH12_INT_XLIE_MASK (1 << LIS2DH12_INT_XLIE_POS)
+
+
+/**
+ * @brief Interrupt source register bitmasks.
+ */
+
+// Bitmasks for IA.
+#define LIS2DH12_INT_IA_POS 6
+#define LIS2DH12_INT_IA_MASK (1 << LIS2DH12_INT_IA_POS)
+
+// Bitmasks for ZH.
+#define LIS2DH12_INT_ZH_POS 5
+#define LIS2DH12_INT_ZH_MASK (1 << LIS2DH12_INT_ZH_POS)
+
+// Bitmasks for ZL.
+#define LIS2DH12_INT_ZL_POS 4
+#define LIS2DH12_INT_ZL_MASK (1 << LIS2DH12_INT_ZL_POS)
+
+// Bitmasks for YH.
+#define LIS2DH12_INT_YH_POS 3
+#define LIS2DH12_INT_YH_MASK (1 << LIS2DH12_INT_YH_POS)
+
+// Bitmasks for YL.
+#define LIS2DH12_INT_YL_POS 2
+#define LIS2DH12_INT_YL_MASK (1 << LIS2DH12_INT_YL_POS)
+
+// Bitmasks for XH.
+#define LIS2DH12_INT_XH_POS 1
+#define LIS2DH12_INT_XH_MASK (1 << LIS2DH12_INT_XH_POS)
+
+// Bitmasks for XL.
+#define LIS2DH12_INT_XL_POS 0
+#define LIS2DH12_INT_XL_MASK (1 << LIS2DH12_INT_XL_POS)
+
+
+/**
+ * @brief Interrupt threshold register bitmasks.
+ */
+
+// Bitmasks for THS.
+#define LIS2DH12_INT_THS_POS 0
+#define LIS2DH12_INT_THS_MASK (0x7F << LIS2DH12_INT_THS_POS)
+
+
+/**
+ * @brief Interrupt duration register bitmasks.
+ */
+
+// Bitmasks for DUR.
+#define LIS2DH12_INT_DUR_POS 0
+#define LIS2DH12_INT_DUR_MASK (0x7F << LIS2DH12_INT_DUR_POS)
+
+
+/**
+ * @brief Click config register bitmasks.
+ */
+
+// Bitmasks for ZD.
+#define LIS2DH12_CLICK_ZD_POS 5
+#define LIS2DH12_CLICK_ZD_MASK (1 << LIS2DH12_CLICK_ZD_POS)
+
+// Bitmasks for ZS.
+#define LIS2DH12_CLICK_ZS_POS 4
+#define LIS2DH12_CLICK_ZS_MASK (1 << LIS2DH12_CLICK_ZS_POS)
+
+// Bitmasks for YD.
+#define LIS2DH12_CLICK_YD_POS 3
+#define LIS2DH12_CLICK_YD_MASK (1 << LIS2DH12_CLICK_YD_POS)
+
+// Bitmasks for YS.
+#define LIS2DH12_CLICK_YS_POS 2
+#define LIS2DH12_CLICK_YS_MASK (1 << LIS2DH12_CLICK_YS_POS)
+
+// Bitmasks for XD.
+#define LIS2DH12_CLICK_XD_POS 1
+#define LIS2DH12_CLICK_XD_MASK (1 << LIS2DH12_CLICK_XD_POS)
+
+// Bitmasks for XS.
+#define LIS2DH12_CLICK_XS_POS 0
+#define LIS2DH12_CLICK_XS_MASK (1 << LIS2DH12_CLICK_XS_POS)
+
+
+/**
+ * @brief Click source register bitmasks.
+ */
+
+// Bitmasks for IA.
+#define LIS2DH12_CLICK_IA_POS 6
+#define LIS2DH12_CLICK_IA_MASK (1 << LIS2DH12_CLICK_IA_POS)
+
+// Bitmasks for DCLICK.
+#define LIS2DH12_CLICK_DCLICK_POS 5
+#define LIS2DH12_CLICK_DCLICK_MASK (1 << LIS2DH12_CLICK_DCLICK_POS)
+
+// Bitmasks for SCLICK.
+#define LIS2DH12_CLICK_SCLICK_POS 4
+#define LIS2DH12_CLICK_SCLICK_MASK (1 << LIS2DH12_CLICK_SCLICK_POS)
+
+// Bitmasks for SIGN.
+#define LIS2DH12_CLICK_SIGN_POS 3
+#define LIS2DH12_CLICK_SIGN_MASK (1 << LIS2DH12_CLICK_SIGN_POS)
+
+// Bitmasks for Z.
+#define LIS2DH12_CLICK_Z_POS 2
+#define LIS2DH12_CLICK_Z_MASK (1 << LIS2DH12_CLICK_Z_POS)
+
+// Bitmasks for Y.
+#define LIS2DH12_CLICK_Y_POS 1
+#define LIS2DH12_CLICK_Y_MASK (1 << LIS2DH12_CLICK_Y_POS)
+
+// Bitmasks for X.
+#define LIS2DH12_CLICK_X_POS 0
+#define LIS2DH12_CLICK_X_MASK (1 << LIS2DH12_CLICK_X_POS)
+
+
+/**
+ * @brief Click threshold register bitmasks.
+ */
+
+// Bitmasks for LIR.
+#define LIS2DH12_CLICK_LIR_POS 7
+#define LIS2DH12_CLICK_LIR_MASK (1 << LIS2DH12_CLICK_LIR_POS)
+
+// Bitmasks for THS.
+#define LIS2DH12_CLICK_THS_POS 0
+#define LIS2DH12_CLICK_THS_MASK (0x7F << LIS2DH12_CLICK_THS_POS)
+
+
+/**
+ * @brief Click time limit register bitmasks.
+ */
+
+// Bitmasks for TLI.
+#define LIS2DH12_CLICK_TLI_POS 0
+#define LIS2DH12_CLICK_TLI_MASK (0x7F << LIS2DH12_CLICK_TLI_POS)
+
+
+/**
+ * @brief Activation threshold register bitmasks.
+ */
+
+// Bitmasks for THS.
+#define LIS2DH12_ACT_THS_POS 0
+#define LIS2DH12_ACT_THS_MASK (0x7F << LIS2DH12_ACT_THS_POS)
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+
+ uint8_t ctrl0;
+ uint8_t temp_cfg;
+ uint8_t ctrl1;
+ uint8_t ctrl2;
+ uint8_t ctrl3;
+ uint8_t ctrl4;
+ uint8_t ctrl5;
+ uint8_t ctrl6;
+ uint8_t reference;
+ uint8_t fifo_ctrl;
+ uint8_t int1_cfg;
+ uint8_t int1_ths;
+ uint8_t int1_dur;
+ uint8_t int2_cfg;
+ uint8_t int2_ths;
+ uint8_t int2_dur;
+ uint8_t click_cfg;
+ uint8_t click_ths;
+ uint8_t time_lim;
+ uint8_t latency;
+ uint8_t time_win;
+ uint8_t act_ths;
+ uint8_t act_dur;
+
+} lis2dh12_instance_t;
+
+/**
+ * @brief Macro for defining sensor instance.
+ */
+#define LIS2DH12_INTERNAL_INSTANCE_DEF(_lis2dh12_inst_name, _p_twi_sensor, _sensor_address) \
+ static lis2dh12_instance_t _lis2dh12_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address \
+ }
+
+
+/**
+ * @brief Macro for setting data acquisition configuration.
+ */
+#define LIS2DH12_INTERNAL_DATA_CFG(_s, _odr, _lp, _z_en, _y_en, _x_en, _scale, _high_res) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_ODR_MASK, LIS2DH12_ODR_POS, _odr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_LP_EN_MASK, LIS2DH12_LP_EN_POS, _lp); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_Z_EN_MASK, LIS2DH12_Z_EN_POS, _z_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_Y_EN_MASK, LIS2DH12_Y_EN_POS, _y_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_X_EN_MASK, LIS2DH12_X_EN_POS, _x_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl4, LIS2DH12_FS_MASK, LIS2DH12_FS_POS, _scale); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl4, LIS2DH12_HR_MASK, LIS2DH12_HR_POS, _high_res)
+
+/**
+ * @brief Function for setting filter configuration.
+ */
+#define LIS2DH12_INTERNAL_FILTER_CFG(_s, _mode, _freq, _d_en, _c_en, _i1_en, _i2_en) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HPM_MASK, LIS2DH12_HPM_POS, _mode); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HPCF_MASK, LIS2DH12_HPCF_POS, _freq); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_FDS_MASK, LIS2DH12_FDS_POS, _d_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HP_C_MASK, LIS2DH12_HP_C_POS, _c_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HP_I1_MASK, LIS2DH12_HP_I1_POS, _i1_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HP_I2_MASK, LIS2DH12_HP_I2_POS, _i2_en)
+
+/**
+ * @brief Macro for configuring INT1 pin.
+ */
+#define LIS2DH12_INTERNAL_INT1_PIN_CFG(_s, _cl, _ia1, _ia2, _zyxda, _wtm, _ovr, _pol, _d4d) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_CLICK_MASK, LIS2DH12_I1_CLICK_POS, _cl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_IA1_MASK, LIS2DH12_I1_IA1_POS, _ia1); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_IA2_MASK, LIS2DH12_I1_IA2_POS, _ia2); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_ZYXDA_MASK, LIS2DH12_I1_ZYXDA_POS, _zyxda); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_WTM_MASK, LIS2DH12_I1_WTM_POS, _wtm); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_OVERRUN_MASK, LIS2DH12_I1_OVERRUN_POS, _ovr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_INT_POLARITY_MASK, LIS2DH12_INT_POLARITY_POS, _pol); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_D4D_INT1_MASK, LIS2DH12_D4D_INT1_POS, _d4d)
+
+/**
+ * @brief Macro for configuring INT2 pin.
+ */
+#define LIS2DH12_INTERNAL_INT2_PIN_CFG(_s, _cl, _ia1, _ia2, _boot, _act, _pol, _d4d) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_CLICK_MASK, LIS2DH12_I2_CLICK_POS, _cl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_IA1_MASK, LIS2DH12_I2_IA1_POS, _ia1); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_IA2_MASK, LIS2DH12_I2_IA2_POS, _ia2); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_BOOT_MASK, LIS2DH12_I2_BOOT_POS, _boot);\
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_ACT_MASK, LIS2DH12_I2_ACT_POS, _act); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_INT_POLARITY_MASK, LIS2DH12_INT_POLARITY_POS, _pol); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_D4D_INT2_MASK, LIS2DH12_D4D_INT2_POS, _d4d)
+
+ /**
+ * @brief Macro for configuring interrupt 1.
+ */
+#define LIS2DH12_INTERNAL_INT1_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_ths, LIS2DH12_INT_THS_MASK, LIS2DH12_INT_THS_POS, _thr); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_dur, LIS2DH12_INT_DUR_MASK, LIS2DH12_INT_DUR_POS, _dur); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_AOI_MASK, LIS2DH12_INT_AOI_POS, _aoi); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_6D_MASK, LIS2DH12_INT_6D_POS, _6d); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_ZHIE_MASK, LIS2DH12_INT_ZHIE_POS, _zh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_ZLIE_MASK, LIS2DH12_INT_ZLIE_POS, _zl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_YHIE_MASK, LIS2DH12_INT_YHIE_POS, _yh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_YLIE_MASK, LIS2DH12_INT_YLIE_POS, _yl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_XHIE_MASK, LIS2DH12_INT_XHIE_POS, _xh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_XLIE_MASK, LIS2DH12_INT_XLIE_POS, _xl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_LIR_INT1_MASK, LIS2DH12_LIR_INT1_POS, _lir)
+
+
+/**
+ * @brief Macro for configuring interrupt 2.
+ */
+#define LIS2DH12_INTERNAL_INT2_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_ths, LIS2DH12_INT_THS_MASK, LIS2DH12_INT_THS_POS, _thr); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_dur, LIS2DH12_INT_DUR_MASK, LIS2DH12_INT_DUR_POS, _dur); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_AOI_MASK, LIS2DH12_INT_AOI_POS, _aoi); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_6D_MASK, LIS2DH12_INT_6D_POS, _6d); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_ZHIE_MASK, LIS2DH12_INT_ZHIE_POS, _zh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_ZLIE_MASK, LIS2DH12_INT_ZLIE_POS, _zl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_YHIE_MASK, LIS2DH12_INT_YHIE_POS, _yh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_YLIE_MASK, LIS2DH12_INT_YLIE_POS, _yl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_XHIE_MASK, LIS2DH12_INT_XHIE_POS, _xh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_XLIE_MASK, LIS2DH12_INT_XLIE_POS, _xl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_LIR_INT2_MASK, LIS2DH12_LIR_INT2_POS, _lir)
+
+/**
+ * @brief Function for setting click configuration.
+ */
+#define LIS2DH12_INTERNAL_CLICK_CFG(_s, _zd, _zs, _yd, _ys, _xd, _xs, _lir, _ths, _lim, _ltc, _win) \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_ZD_MASK, LIS2DH12_CLICK_ZD_POS, _zd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_ZS_MASK, LIS2DH12_CLICK_ZD_POS, _zd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_YD_MASK, LIS2DH12_CLICK_YD_POS, _yd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_YS_MASK, LIS2DH12_CLICK_YS_POS, _ys); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_XD_MASK, LIS2DH12_CLICK_XD_POS, _xd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_XS_MASK, LIS2DH12_CLICK_XS_POS, _xs); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_ths, LIS2DH12_CLICK_LIR_MASK, LIS2DH12_CLICK_LIR_POS, _lir); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_ths, LIS2DH12_CLICK_THS_MASK, LIS2DH12_CLICK_THS_POS, _ths); \
+ NRF_TWI_SENSOR_REG_SET(_s.time_lim, LIS2DH12_CLICK_TLI_MASK, LIS2DH12_CLICK_TLI_POS, _lim); \
+ _s.latency = _ltc; \
+ _s.time_win = _win
+
+ /**
+ * @brief Macro for setting sleep configuration.
+ */
+#define LIS2DH12_INTERNAL_SLEEP_CFG(_s, _ths, _dur) \
+ NRF_TWI_SENSOR_REG_SET(_s.act_ths, LIS2DH12_ACT_THS_MASK, LIS2DH12_ACT_THS_POS, _ths); \
+ _s.act_dur = _dur
+
+/**
+ * @brief Macro for setting reference value for interrupt generation.
+ */
+#define LIS2DH12_INTERNAL_REF_SET(_s, _ref) \
+ _s.reference = _ref
+
+
+/**
+ * @brief Macro for setting FIFO configuration.
+ */
+#define LIS2DH12_INTERNAL_FIFO_CFG(_s, _en, _mode, _t_sel, _t_thr) \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LIS2DH12_FM_MASK, LIS2DH12_FM_POS, _mode); \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LIS2DH12_TR_MASK, LIS2DH12_TR_POS, _t_sel); \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LIS2DH12_FTH_MASK, LIS2DH12_FTH_POS, _t_thr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_FIFO_EN_MASK, LIS2DH12_FIFO_EN_POS, _en)
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t lis2dh12_temp_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_STATUS_AUX,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_who_am_i_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_WHO_AM_I,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_STATUS,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_fifo_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_FIFO_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_int1_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_INT1_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_int2_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_INT2_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_click_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_CLICK_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIS2DH12_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c
new file mode 100644
index 0000000..8dee20a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c
@@ -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.
+ *
+ */
+
+#include "lps22hb.h"
+
+ret_code_t lps22hb_init(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ p_instance->interrupt_cfg = 0;
+ p_instance->ctrl_reg[0] = 0;
+ p_instance->ctrl_reg[1] = LPS22HB_CTRL_REG2_DEFAULT;
+ p_instance->ctrl_reg[2] = 0;
+ p_instance->fifo_ctrl = 0;
+ ret_code_t err_code;
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < LPS22HB_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ err_code = lps22hb_cfg_commit(p_instance);
+ return err_code;
+}
+
+ret_code_t lps22hb_autorifp_enable(lps22hb_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg = p_instance->interrupt_cfg;
+ if (enable == true)
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_AUTORIFP_MASK, LPS22HB_AUTORIFP_POS, 1);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_RESET_ARP_MASK, LPS22HB_RESET_ARP_POS, 1);
+ }
+ uint8_t send_msg[] = {
+ LPS22HB_REG_INTERRUPT_CONFIG,
+ reg
+ };
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t lps22hb_autozero_enable(lps22hb_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg = p_instance->interrupt_cfg;
+ if (enable == true)
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_AUTOZERO_MASK, LPS22HB_AUTOZERO_POS, 1);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_RESET_AZ_MASK, LPS22HB_RESET_AZ_POS, 1);
+ }
+ uint8_t send_msg[] = {
+ LPS22HB_REG_INTERRUPT_CONFIG,
+ reg
+ };
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+
+void lps22hb_data_rate_set(lps22hb_instance_t * p_instance, lps22hb_odr_t odr)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg[0], LPS22HB_ODR_MASK, LPS22HB_ODR_POS, odr);
+}
+
+ret_code_t lps22hb_data_read(lps22hb_instance_t * p_instance,
+ lps22hb_data_callback_t user_callback,
+ lps22hb_data_t * p_out_data,
+ uint8_t samples)
+{
+ ASSERT(p_instance != NULL);
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_PRESS_OUT_XL,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) p_out_data,
+ samples * LPS22HB_BYTES_PER_SAMPLE);
+ return err_code;
+}
+
+void lps22hb_data_decode(lps22hb_data_t * p_data, uint8_t samples)
+{
+ ASSERT(p_data != NULL);
+ lps22hb_raw_data_t * p_in_data = (lps22hb_raw_data_t *) p_data;
+ uint32_t pres;
+ uint16_t temp;
+ for (int i = samples-1; i >= 0; i--)
+ {
+ pres = ((uint32_t) p_in_data[i].press_out_xl) |
+ (((uint32_t) p_in_data[i].press_out_l) << 8) |
+ (((uint32_t) p_in_data[i].press_out_h) << 16);
+ pres <<= 8;
+ temp = ((uint16_t) p_in_data[i].temp_out_l) |
+ (((uint16_t) p_in_data[i].temp_out_h) << 8);
+ // Dividing by 256 because signed integer can't be shifted by 8
+ p_data[i].pressure = *((int32_t *) &pres) / 256;
+ p_data[i].temperature = *((int16_t *) &temp);
+ }
+}
+
+ret_code_t lps22hb_threshold_set(lps22hb_instance_t * p_instance, uint16_t thr)
+{
+ ASSERT(p_instance != NULL);
+ thr *= 16;
+ uint8_t send_msg[] = {
+ LPS22HB_REG_THS_P_L,
+ thr & 0x00FFU,
+ thr >> 8
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
+
+ret_code_t lps22hb_ref_pressure_set(lps22hb_instance_t * p_instance, int32_t pressure)
+{
+ ASSERT(p_instance != NULL);
+ // Multiplying by 256 because signed integer can't be shifted by 8
+ pressure *= 256;
+ uint32_t pres = *((uint32_t *) &pressure);
+ pres >>= 8;
+ uint8_t send_msg[] = {
+ LPS22HB_REG_REF_P_XL,
+ pres & 0x00FFU,
+ (pres >> 8) & 0x00FFU,
+ (pres >> 16) & 0x00FFU
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
+
+ret_code_t lps22hb_offset_set(lps22hb_instance_t * p_instance, int16_t offset)
+{
+ ASSERT(p_instance != NULL);
+ offset *= 16;
+ uint16_t off = *((uint16_t *) &offset);
+ uint8_t send_msg[] = {
+ LPS22HB_REG_RPDS_L,
+ off & 0x00FFU,
+ off >> 8
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
+
+
+
+ret_code_t lps22hb_cfg_commit(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ p_instance->ctrl_reg[1] |= LPS22HB_CTRL_REG2_DEFAULT;
+ p_instance->ctrl_reg[0] &= ~LPS22HB_CTRL1_VALID_MASK;
+ p_instance->ctrl_reg[1] &= ~LPS22HB_CTRL2_VALID_MASK;
+
+ ret_code_t err_code;
+
+ err_code = nrf_twi_sensor_reg_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_INTERRUPT_CONFIG,
+ &p_instance->interrupt_cfg,
+ 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_twi_sensor_reg_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_CTRL1,
+ p_instance->ctrl_reg,
+ 3);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_twi_sensor_reg_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_FIFO_CTRL,
+ &p_instance->fifo_ctrl,
+ 1);
+ return err_code;
+}
+
+ret_code_t lps22hb_sw_reset(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg[1];
+ NRF_TWI_SENSOR_REG_SET(reg_val, LPS22HB_SWRESET_MASK, LPS22HB_SWRESET_POS, 1);
+
+ uint8_t send_msg[] = {
+ LPS22HB_REG_CTRL2,
+ reg_val
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+ return err_code;
+}
+
+ret_code_t lps22hb_boot(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg[1];
+ NRF_TWI_SENSOR_REG_SET(reg_val, LPS22HB_BOOT_MASK, LPS22HB_BOOT_POS, 1);
+
+ uint8_t send_msg[] = {
+ LPS22HB_REG_CTRL2,
+ reg_val
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+ return err_code;
+}
+
+ret_code_t lps22hb_oneshot(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg[1];
+ NRF_TWI_SENSOR_REG_SET(reg_val, LPS22HB_ONE_SHOT_MASK, LPS22HB_ONE_SHOT_POS, 1);
+
+ uint8_t send_msg[] = {
+ LPS22HB_REG_CTRL2,
+ reg_val
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+ return err_code;
+}
+
+ret_code_t lps22hb_low_power_enable(lps22hb_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ LPS22HB_REG_RES_CONF,
+ enable
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h
new file mode 100644
index 0000000..c61ee6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h
@@ -0,0 +1,512 @@
+/**
+ * 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 LPS22HB_H
+#define LPS22HB_H
+
+#include "nrf_twi_sensor.h"
+#include "lps22hb_internal.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define LPS22HB_BASE_ADDRESS_LOW 0x5CU
+#define LPS22HB_BASE_ADDRESS_HIGH 0x5DU
+
+// WHO_AM_I register value
+#define LPS22HB_WHO_AM_I 0xB1
+
+// Minimum nrf_twi_sensor message buffer size and nrf_twi_mngr queue length.
+#define LPS22HB_MIN_QUEUE_SIZE 4
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref LPS22HB_INSTANCE DEF.
+ * After that it has to be initialized using @ref lps22hb_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * There are two ways in which sensor settings are set:
+ *
+ * First one are asynchronous macros, using them does not change real sensor settings
+ * until @ref lps22hb_cfg_commit is called.
+ * Example:
+ * LPS22HB_DATA_CFG(m_sensor1, LPS22HB_ODR_POWERDOWN, false, false);
+ * LPS22HB_FIFO_CFG(m_sensor1, LPS22HB_STREAM, true, false, 15);
+ * lps22hb_cfg_commit(&m_sensor1);
+ *
+ * Second way are functions, functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ * Example:
+ * lps22hb_low_power_enable(&m_sensor1, true);
+ * lps22hb_offset_set(&m_sensor1, -27);
+ *
+ * There are designated functions to read status sensor registers e.g. @ref lps22hb_int_source_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * uint8_t ia = NRF_TWI_SENSOR_REG_VAL_GET(int_source_reg, LPS22HB_IA_MASK, LPS22HB_IA_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+
+/**
+ * @brief Output data rate settings.
+ */
+typedef enum
+{
+ LPS22HB_ODR_POWERDOWN,
+ LPS22HB_ODR_1HZ,
+ LPS22HB_ODR_10HZ,
+ LPS22HB_ODR_25HZ,
+ LPS22HB_ODR_50HZ,
+ LPS22HB_ODR_75HZ
+} lps22hb_odr_t;
+
+/**
+ * @brief Fifo mode settings.
+ */
+typedef enum
+{
+ LPS22HB_BYPASS,
+ LPS22HB_FIFO,
+ LPS22HB_STREAM,
+ LPS22HB_STREAM_TO_FIFO,
+ LPS22HB_BYPASS_TO_STREAM,
+ LPS22HB_RESERVED_FIFO,
+ LPS22HB_DYNAMIC_STREAM,
+ LPS22HB_BYPASS_TO_FIFO
+} lps22hb_fifo_mode_t;
+
+/**
+ * @brief Low pass filter configuration.
+ */
+typedef enum
+{
+ LPS22HB_LPFP_DISABLE = 1,
+ LPS22HB_LPFP_ODR_DIV_9,
+ LPS22HB_LPFP_ODR_DIV_20
+} lps22hb_lpfp_t;
+
+/**
+ * @brief Pressure and temperature output data.
+ *
+ * @note To get pressure in hPa it has to be divided by 4096.
+ * To get temperature in degrees it has to be divided by 100.
+ */
+typedef struct
+{
+ int32_t pressure;
+ int16_t temperature;
+} lps22hb_data_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_raw_data Pointer to raw sensor data structure.
+ */
+
+typedef void (* lps22hb_data_callback_t)(ret_code_t result, lps22hb_data_t * p_raw_data);
+
+
+/**
+ * @brief Macro creating lps22hb sensor instance.
+ *
+ * @param[in] _lps22hb_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance.
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define LPS22HB_INSTANCE_DEF(_lps22hb_inst_name, _p_twi_sensor, _sensor_address) \
+ LPS22HB_INTERNAL_INSTANCE_DEF(_lps22hb_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * ===============================================================================================
+ * @brief Sensor configuration macros.
+ *
+ * @note After setting configuration using these macros, it has to be committed to sensor
+ * using @ref lps22hb_cfg_commit
+ */
+
+/**
+ * @brief Macro for interrupt configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _diff_en Enable interrupt generation. True if enabled.
+ * @param[in] _lir Latch interrupt request to INT_SOURCE register. True if enabled.
+ * @param[in] _ple Enable interrupt generation on pressure low event. True if enabled.
+ * @param[in] _phe Enable interrupt generation on pressure high event. True if enabled.
+ */
+#define LPS22HB_INT_CFG(_s, _diff_en, _lir, _ple, _phe)\
+ LPS22HB_INTERNAL_INT_CFG(_s, _diff_en, _lir, _ple, _phe)
+/**
+ * @brief Macro for data acquisition configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _odr Desired output data rate. @ref lps22hb_odr_t
+ * @param[in] _f_en Enables filter. True if enabled.
+ * @param[in] _f_cfg Filter configuration.
+ * @arg true Filter bandwidth is ODR/20
+ * @arg false Filter bandwidth is ODR/9
+ */
+#define LPS22HB_DATA_CFG(_s, _odr, _f_en, _f_cfg)\
+ LPS22HB_INTERNAL_DATA_CFG(_s, _odr, _f_en, _f_cfg)
+
+/**
+ * @brief Macro for FIFO configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _f_mode FIFO mode. @ref lps22hb_fifo_mode_t
+ * @param[in] _f_en Enable FIFO. True if enabled.
+ * @param[in] _f_stop Stop on FIFO watermark. True if enabled.
+ * @param[in] _f_wtm FIFO watermark value. Between 0 and 31.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+#define LPS22HB_FIFO_CFG(_s, _f_mode, _f_en, _f_stop, _f_wtm)\
+ LPS22HB_INTERNAL_FIFO_CFG(_s, _f_mode, _f_en, _f_stop, _f_wtm)
+
+/**
+ * @brief Macro for INT_DRDY pin configuration.
+ * @param[in] _s Sensor instance.
+ * @param[in] _activ Active state.
+ * @arg true Active low.
+ * @arg false Active high.
+ * @param[in] _pp_od Pin operation.
+ * @arg true Open drain.
+ * @arg false Push-pull.
+ * @param[in] _fss FIFO full flag. True if enabled.
+ * @param[in] _fth FIFO watermark status. True if enabled.
+ * @param[in] _ovr FIFO overrun interrupt. True if enabled.
+ * @param[in] _drdy Data Ready signal. True if enabled.
+ * @param[in] _high Pressure higher than interrupt threshold. True if enabled.
+ * @param[in] _low Pressure lower than interrupt threshold. True if enabled.
+ */
+#define LPS22HB_DRDY_CFG(_s, _activ, _pp_od, _fss, _fth, _ovr, _drdy, _high, _low)\
+ LPS22HB_INTERNAL_DRDY_CFG(_s, _activ, _pp_od, _fss, _fth, _ovr, _drdy, _high, _low)
+/**
+ * ===============================================================================================
+ */
+
+
+/**
+ * @brief Function for initializing lps22hb sensor.
+ *
+ * Writes configuration data in sensor instance to sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance created by macro
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_init(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for enabling autorifp.
+ *
+ * @param[in] p_instance Pointer to sensor instance
+ * @param[in] enable Autorifp setting.
+ * @arg true Autorifp is enabled.
+ * @arg false Autorifp is disabled and reset.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_autorifp_enable(lps22hb_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for enabling autozero.
+ *
+ * @param[in] p_instance Pointer to sensor instance
+ * @param[in] enable Autozero setting.
+ * @arg true Autozero is enabled.
+ * @arg false Autozero is disabled and reset.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_autozero_enable(lps22hb_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function performing software reset.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_sw_reset(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function performing boot.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_boot(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function setting oneshot.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_oneshot(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for reading pressure and temperature data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_callback Function to be called when data is gathered.
+ * @param[out] p_out_data Pointer to raw data buffer.
+ * @param[in] samples Number of data samples to read.
+ *
+ * @note Data can be read in two ways. With or without sensors FIFO.
+ * FIFO mode depends on FIFO mode set using lps22hb_fifo_mode_set function.
+ * FIFO is enabled using lps22hb_fifo_enable function.
+ * Without FIFO only one sample can be acquired, p_out_data can be pointer to single variable.
+ * With FIFO enabled, data can be read in burst mode, p_out_data table has to be same
+ * or bigger than number of samples to read.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t lps22hb_data_read(lps22hb_instance_t * p_instance,
+ lps22hb_data_callback_t user_callback,
+ lps22hb_data_t * p_out_data,
+ uint8_t samples);
+
+/**
+ * @brief Function for converting raw sensor data to real.
+ *
+ * @param[in/out] p_data Pointer to data to be processed.
+ * @param[in] samples Number of samples to be processed.
+ *
+ * @note After data is processed, structure contains pressure in hPa*4096
+ * and temperature in Celsius degrees*100
+ */
+void lps22hb_data_decode(lps22hb_data_t * p_data, uint8_t samples);
+
+/**
+ * @brief Function for setting reference pressure.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] pressure Reference pressure in hPa*4096
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_ref_pressure_set(lps22hb_instance_t * p_instance, int32_t pressure);
+
+/**
+ * @brief Function for setting pressure offset.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] offset Pressure offset in hPa.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_offset_set(lps22hb_instance_t * p_instance, int16_t offset);
+
+/**
+ * @brief Function for setting interrupt threshold.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] threshold Interrupt threshold in hPa.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_threshold_set(lps22hb_instance_t * p_instance, uint16_t threshold);
+
+/**
+ * @brief Function for enabling low power mode.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable Enable low power mode. True if enabled.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_low_power_enable(lps22hb_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for setting sensor configuration.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_cfg_commit(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for resetting filter.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+__STATIC_INLINE ret_code_t lps22hb_reset_filter(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for reading who am i register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_who_am_i_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading interrupt source register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_int_source_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading fifo status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_fifo_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t lps22hb_reset_filter(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ static uint8_t temp;
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_LPFP_RES,
+ NULL,
+ &temp,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_who_am_i_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_WHO_AM_I,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_int_source_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_INT_SOURCE,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_fifo_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_FIFO_STATUS,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_STATUS,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LPS22HB_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h
new file mode 100644
index 0000000..68d636a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h
@@ -0,0 +1,365 @@
+/**
+ * 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 LPS22HB_INTERNAL_H
+#define LPS22HB_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LPS22HB_BYTES_PER_SAMPLE 5
+
+/**
+ * @brief LPS22HB sensor registers.
+ */
+#define LPS22HB_REG_INTERRUPT_CONFIG 0x0B
+#define LPS22HB_REG_THS_P_L 0x0C
+#define LPS22HB_REG_THS_P_H 0x0D
+#define LPS22HB_REG_WHO_AM_I 0x0F
+#define LPS22HB_REG_CTRL1 0x10
+#define LPS22HB_REG_CTRL2 0x11
+#define LPS22HB_REG_CTRL3 0x12
+#define LPS22HB_REG_FIFO_CTRL 0x14
+#define LPS22HB_REG_REF_P_XL 0x15
+#define LPS22HB_REG_REF_P_L 0x16
+#define LPS22HB_REG_REF_P_H 0x17
+#define LPS22HB_REG_RPDS_L 0x18
+#define LPS22HB_REG_RPDS_H 0x19
+#define LPS22HB_REG_RES_CONF 0x1A
+#define LPS22HB_REG_INT_SOURCE 0x25
+#define LPS22HB_REG_FIFO_STATUS 0x26
+#define LPS22HB_REG_STATUS 0x27
+#define LPS22HB_REG_PRESS_OUT_XL 0x28
+#define LPS22HB_REG_PRESS_OUT_L 0x29
+#define LPS22HB_REG_PRESS_OUT_H 0x2A
+#define LPS22HB_REG_TEMP_OUT_L 0x2B
+#define LPS22HB_REG_TEMP_OUT_H 0x2C
+#define LPS22HB_REG_LPFP_RES 0x33
+/**
+ * @brief Interrupt config register bitmasks.
+ */
+
+// Bitmasks for AUTORIFP.
+#define LPS22HB_AUTORIFP_POS 7
+#define LPS22HB_AUTORIFP_MASK (1 << LPS22HB_AUTORIFP_POS)
+
+// Bitmasks for RESET_ARP.
+#define LPS22HB_RESET_ARP_POS 6
+#define LPS22HB_RESET_ARP_MASK (1 << LPS22HB_RESET_ARP_POS)
+
+// Bitmasks for AUTOZERO.
+#define LPS22HB_AUTOZERO_POS 5
+#define LPS22HB_AUTOZERO_MASK (1 << LPS22HB_AUTOZERO_POS)
+
+// Bitmasks for RESET_AZ.
+#define LPS22HB_RESET_AZ_POS 4
+#define LPS22HB_RESET_AZ_MASK (1 << LPS22HB_RESET_AZ_POS)
+
+// Bitmasks for DIFF_EN.
+#define LPS22HB_DIFF_EN_POS 3
+#define LPS22HB_DIFF_EN_MASK (1 << LPS22HB_DIFF_EN_POS)
+
+// Bitmasks for LIR.
+#define LPS22HB_LIR_POS 2
+#define LPS22HB_LIR_MASK (1 << LPS22HB_LIR_POS)
+
+// Bitmasks for PLE.
+#define LPS22HB_PLE_POS 1
+#define LPS22HB_PLE_MASK (1 << LPS22HB_PLE_POS)
+
+// Bitmasks for PHE.
+#define LPS22HB_PHE_POS 0
+#define LPS22HB_PHE_MASK (1 << LPS22HB_PHE_POS)
+
+
+/**
+ * @brief Control register 1 bitmasks.
+ */
+
+// Register validity bitmask.
+#define LPS22HB_CTRL1_VALID_MASK 0x80
+
+// Bitmasks for ODR.
+#define LPS22HB_ODR_POS 4
+#define LPS22HB_ODR_MASK (7 << LPS22HB_ODR_POS)
+
+// Bitmasks for EN_LPFP.
+#define LPS22HB_EN_LPFP_POS 3
+#define LPS22HB_EN_LPFP_MASK (1 << LPS22HB_EN_LPFP_POS)
+
+// Bitmasks for LPFP_CFG.
+#define LPS22HB_LPFP_CFG_POS 2
+#define LPS22HB_LPFP_CFG_MASK (1 << LPS22HB_LPFP_CFG_POS)
+
+// Bitmasks for BDU.
+#define LPS22HB_BDU_POS 1
+#define LPS22HB_BDU_MASK (1 << LPS22HB_BDU_POS)
+
+// Bitmasks for SIM.
+#define LPS22HB_SIM_POS 0
+#define LPS22HB_SIM_MASK (1 << LPS22HB_SIM_POS)
+
+
+/**
+ * @brief Control register 2 bitmasks.
+ */
+
+// Register validity bitmask.
+#define LPS22HB_CTRL2_VALID_MASK 0x02
+
+// Bitmasks for BOOT.
+#define LPS22HB_BOOT_POS 7
+#define LPS22HB_BOOT_MASK (1 << LPS22HB_BOOT_POS)
+
+// Bitmasks for FIFO_EN.
+#define LPS22HB_FIFO_EN_POS 6
+#define LPS22HB_FIFO_EN_MASK (1 << LPS22HB_FIFO_EN_POS)
+
+// Bitmasks for STOP_ON_FTH.
+#define LPS22HB_STOP_ON_FTH_POS 5
+#define LPS22HB_STOP_ON_FTH_MASK (1 << LPS22HB_STOP_ON_FTH_POS)
+
+// Bitmasks for IF_ADD_INC.
+#define LPS22HB_IF_ADD_INC_POS 4
+#define LPS22HB_IF_ADD_INC_MASK (1 << LPS22HB_IF_ADD_INC_POS)
+
+// Bitmasks for I2C_DIS.
+#define LPS22HB_I2C_DIS_POS 3
+#define LPS22HB_I2C_DIS_MASK (1 << LPS22HB_I2C_DIS_POS)
+
+// Bitmasks for SWRESET.
+#define LPS22HB_SWRESET_POS 2
+#define LPS22HB_SWRESET_MASK (1 << LPS22HB_SWRESET_POS)
+
+// Bitmasks for ONE_SHOT.
+#define LPS22HB_ONE_SHOT_POS 0
+#define LPS22HB_ONE_SHOT_MASK (1 << LPS22HB_ONE_SHOT_POS)
+
+
+/**
+ * @brief Control register 3 bitmasks.
+ */
+
+// Bitmasks for INT_H_L.
+#define LPS22HB_INT_H_L_POS 7
+#define LPS22HB_INT_H_L_MASK (1 << LPS22HB_INT_H_L_POS)
+
+// Bitmasks for PP_OD.
+#define LPS22HB_PP_OD_POS 6
+#define LPS22HB_PP_OD_MASK (1 << LPS22HB_PP_OD_POS)
+
+// Bitmasks for F_FSS5.
+#define LPS22HB_F_FSS5_POS 5
+#define LPS22HB_F_FSS5_MASK (1 << LPS22HB_F_FSS5_POS)
+
+// Bitmasks for F_FTH.
+#define LPS22HB_F_FTH_POS 4
+#define LPS22HB_F_FTH_MASK (1 << LPS22HB_F_FTH_POS)
+
+// Bitmasks for F_OVR.
+#define LPS22HB_F_OVR_POS 3
+#define LPS22HB_F_OVR_MASK (1 << LPS22HB_F_OVR_POS)
+
+// Bitmasks for DRDY.
+#define LPS22HB_DRDY_POS 2
+#define LPS22HB_DRDY_MASK (1 << LPS22HB_DRDY_POS)
+
+// Bitmasks for INT_S.
+#define LPS22HB_INT_S_POS 0
+#define LPS22HB_INT_S_MASK (3 << LPS22HB_INT_S_POS)
+
+
+/**
+ * @brief Fifo control register bitmasks.
+ */
+
+// Bitmasks for F_MODE.
+#define LPS22HB_F_MODE_POS 5
+#define LPS22HB_F_MODE_MASK (7 << LPS22HB_F_MODE_POS)
+
+// Bitmasks for WTM
+#define LPS22HB_WTM_POS 0
+#define LPS22HB_WTM_MASK (0x1F << LPS22HB_WTM_POS)
+
+
+/**
+ * @brief Low power mode register bitmasks.
+ */
+
+// Register validity bitmask.
+#define LPS22HB_RES_CONF_VALID_MASK 0xFE
+
+// Bitmasks for LC_EN
+#define LPS22HB_LC_EN_POS 0
+#define LPS22HB_LC_EN_MASK (1 << LPS22HB_LC_EN_POS)
+
+
+/**
+ * @brief INT source register bitmasks.
+ */
+
+// Bitmasks for IA
+#define LPS22HB_IA_POS 2
+#define LPS22HB_IA_MASK (1 << LPS22HB_IA_POS)
+
+// Bitmasks for PL
+#define LPS22HB_PL_POS 1
+#define LPS22HB_PL_MASK (1 << LPS22HB_PL_POS)
+
+// Bitmasks for PH
+#define LPS22HB_PH_POS 0
+#define LPS22HB_PH_MASK (1 << LPS22HB_PH_POS)
+
+
+/**
+ * @brief FIFO status register bitmasks.
+ */
+
+// Bitmasks for FTH_FIFO
+#define LPS22HB_FTH_FIFO_POS 7
+#define LPS22HB_FTH_FIFO_MASK (1 << LPS22HB_FTH_FIFO_POS)
+
+// Bitmasks for OVR
+#define LPS22HB_OVR_POS 6
+#define LPS22HB_OVR_MASK (1 << LPS22HB_OVR_POS)
+
+// Bitmasks for stored data level
+#define LPS22HB_FSS_POS 0
+#define LPS22HB_FSS_MASK (0x3F << LPS22HB_FSS_POS)
+
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for T_OR.
+#define LPS22HB_T_OR_POS 5
+#define LPS22HB_T_OR_MASK (1 << LPS22HB_T_OR_POS)
+
+// Bitmasks for P_OR.
+#define LPS22HB_P_OR_POS 4
+#define LPS22HB_P_OR_MASK (1 << LPS22HB_P_OR_POS)
+
+// Bitmasks for T_DA.
+#define LPS22HB_T_DA_POS 1
+#define LPS22HB_T_DA_MASK (1 << LPS22HB_T_DA_POS)
+
+// Bitmasks for P_DA.
+#define LPS22HB_P_DA_POS 0
+#define LPS22HB_P_DA_MASK (1 << LPS22HB_P_DA_POS)
+
+/**
+ * @brief Config registers defaults.
+ */
+#define LPS22HB_CTRL_REG2_DEFAULT 0x10
+
+/**
+ * @brief Raw pressure and temperature data.
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ uint8_t press_out_xl;
+ uint8_t press_out_l;
+ uint8_t press_out_h;
+ uint8_t temp_out_l;
+ uint8_t temp_out_h;
+} lps22hb_raw_data_t;
+
+/**
+ * @brief Structure holding sensor instance
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+
+ uint8_t interrupt_cfg;
+ uint8_t ctrl_reg[3];
+ uint8_t fifo_ctrl;
+} lps22hb_instance_t;
+
+#define LPS22HB_INTERNAL_INSTANCE_DEF(_lps22hb_inst_name, _p_twi_sensor, _sensor_address) \
+ static lps22hb_instance_t _lps22hb_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address, \
+ }
+
+#define LPS22HB_INTERNAL_INT_CFG(_s, _diff_en, _lir, _ple, _phe) \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_DIFF_EN_MASK, LPS22HB_DIFF_EN_POS, _diff_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_LIR_MASK, LPS22HB_LIR_POS, _lir); \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_PLE_MASK, LPS22HB_PLE_POS, _ple); \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_PHE_MASK, LPS22HB_PHE_POS, _phe);
+
+#define LPS22HB_INTERNAL_DATA_CFG(_s, _odr, _f_en, _f_cfg) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[0], LPS22HB_ODR_MASK, LPS22HB_ODR_POS, _odr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[0], LPS22HB_EN_LPFP_MASK, LPS22HB_EN_LPFP_POS, _f_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[0], LPS22HB_LPFP_CFG_MASK, LPS22HB_LPFP_CFG_POS, _f_cfg);
+
+
+#define LPS22HB_INTERNAL_FIFO_CFG(_s, _f_mode, _f_en, _f_stop, _f_wtm) \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LPS22HB_F_MODE_MASK, LPS22HB_F_MODE_POS, _f_mode); \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LPS22HB_WTM_MASK, LPS22HB_WTM_POS, _f_wtm); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[1], LPS22HB_FIFO_EN_MASK, LPS22HB_FIFO_EN_POS, _f_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[1], \
+ LPS22HB_STOP_ON_FTH_MASK, \
+ LPS22HB_STOP_ON_FTH_POS, \
+ _f_stop)
+
+#define LPS22HB_INTERNAL_DRDY_CFG(_s, _activ, _pp_od, _fss, _fth, _ovr, _drdy, _high, _low) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_INT_H_L_MASK, LPS22HB_INT_H_L_POS, _activ); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_PP_OD_MASK, LPS22HB_PP_OD_POS, _pp_od); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_F_FSS5_MASK, LPS22HB_F_FSS5_POS, _fss); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_F_FTH_MASK, LPS22HB_F_FTH_POS, _fth); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_F_OVR_MASK, LPS22HB_F_OVR_POS, _ovr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], \
+ LPS22HB_INT_S_MASK, \
+ LPS22HB_INT_S_MASK, \
+ (_low << 1) + _high);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LPS22HB_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c
new file mode 100644
index 0000000..bd765a1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c
@@ -0,0 +1,71 @@
+/**
+ * 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 "max9850.h"
+
+#include <string.h>
+
+ret_code_t max9850_init(max9850_config_t const * p_max9850)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ ret = nrf_drv_twi_init(&p_max9850->twi, &p_max9850->twi_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_drv_twi_enable(&p_max9850->twi);
+
+ /*Probe device*/
+ uint8_t rx[] = {0};
+ ret = nrf_drv_twi_rx(&p_max9850->twi, p_max9850->twi_addr, rx, sizeof(rx));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ uint8_t regs[sizeof(max9850_regmap_t) + 1];
+
+ regs[0] = 0x00;
+ memcpy(regs + 1, &p_max9850->regmap, sizeof(max9850_regmap_t));
+
+ /*Write configuration*/
+ return nrf_drv_twi_tx(&p_max9850->twi, p_max9850->twi_addr, regs, sizeof(regs), false);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h
new file mode 100644
index 0000000..043f6c3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h
@@ -0,0 +1,130 @@
+/**
+ * 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 MAX9850_H__
+#define MAX9850_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include "nrf_drv_twi.h"
+
+/**
+ * @brief Default MAX9850 TWI configuration
+ *
+ * @param scl_pin SCL pin number
+ * @param sda_pin SDA pin number
+ */
+#define MAX9850_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \
+ .scl = scl_pin, \
+ .sda = sda_pin, \
+ .frequency = NRF_DRV_TWI_FREQ_100K, \
+ .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \
+ .clear_bus_init = false, \
+ .hold_bus_uninit = false \
+}
+
+/**
+ * @brief Internal MAX9850 register map
+ * */
+typedef struct {
+ uint8_t status_a; //!< Status register A (R)
+ uint8_t status_b; //!< Status register B (R)
+ uint8_t volume; //!< Volume control (RW)
+ uint8_t general_purpose; //!< General purpose register (RW)
+ uint8_t interrupt_enable; //!< Interrupt enable (RW)
+ uint8_t enable; //!< Enable register (RW)
+ uint8_t clock; //!< Clock control (RW)
+ uint8_t charge_pump; //!< Charge pump (RW)
+ uint8_t lrclk_msb; //!< LRCLK MSB register (RW)
+ uint8_t lrclk_lsb; //!< LRCLK LSB register (RW)
+ uint8_t digital_audio; //!< Digital audio (RW)
+} max9850_regmap_t;
+
+/**
+ * @brief MAX9850 register map after reset
+ * */
+#define MAX9850_DEFAULT_REGMAP() { \
+ .status_a = 0, \
+ .status_b = 0, \
+ .volume = 0x0C, \
+ .general_purpose = 0, \
+ .interrupt_enable = 0, \
+ .enable = 0, \
+ .clock = 0, \
+ .charge_pump = 0, \
+ .lrclk_msb = 0, \
+ .lrclk_lsb = 0, \
+ .digital_audio = 0, \
+}
+
+/**
+ * @brief Helper macro for creating MAX9850 TWI address
+ * */
+#define MAX9850_TWI_ADDR(v) (0x10 + (v))
+
+
+/**
+ * @brief MAX9850 configuration
+ * */
+typedef struct {
+ nrf_drv_twi_t twi; //!< TWI instance
+ nrf_drv_twi_config_t twi_cfg; //!< TWI configuration
+ max9850_regmap_t regmap; //!< MAX9850 register map
+ uint8_t twi_addr; //!< MAX9850 TWI address
+} max9850_config_t;
+
+/**
+ * @brief Initializes MAX9850 IC
+ *
+ * @param p_max9850 MAX9850 configuration
+ *
+ * @return Standard error code
+ * */
+ret_code_t max9850_init(max9850_config_t const * p_max9850);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAX9850_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c
new file mode 100644
index 0000000..de720e7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.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 "mcp4725.h"
+#include "nrf_drv_twi.h"
+#include "nrf_delay.h"
+#include "boards.h"
+#include "app_util_platform.h"
+
+/*lint ++flb "Enter library region" */
+#define MCP4725_BASE_ADDRESS 0x60 //!< MCP4725 base address
+
+#define MCP4725_DAC_ADDRESS 0x40 //!< MCP4725 write-to-dac register
+#define MCP4725_EEPROM_ADDRESS 0x60 //!< MCP4725 write-to-eeprom register
+
+#define RDY_BIT_POS 0x07 //!< Position of RDY bit
+
+/* TWI instance. */
+static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID_USED);
+
+/* Twi transfer indicators. */
+volatile bool m_xfer_done = false;
+volatile bool m_read_done = false;
+
+/**
+ * @brief TWI events handler.
+ */
+static void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
+{
+ switch (p_event->type)
+ {
+ case NRF_DRV_TWI_EVT_DONE:
+ if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
+ {
+ m_xfer_done = true;
+ }
+ if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
+ {
+ m_read_done = true;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief TWI initialization.
+ *
+ * @param[in] p_pins_config Pointer to structere holding pins numbers to be used by TWI.
+ */
+static ret_code_t twi_init(mcp4725_pins_config_t const * p_pins_config)
+{
+ ret_code_t err_code;
+
+ const nrf_drv_twi_config_t twi_mcp4725_config = {
+ .scl = p_pins_config->scl_pin,
+ .sda = p_pins_config->sda_pin,
+ .frequency = NRF_DRV_TWI_FREQ_100K,
+ .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
+ .clear_bus_init = false
+ };
+
+ err_code = nrf_drv_twi_init(&m_twi, &twi_mcp4725_config, twi_handler, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ nrf_drv_twi_enable(&m_twi);
+ return NRF_SUCCESS;
+}
+
+ret_code_t mcp4725_setup(mcp4725_pins_config_t const * p_pins_config)
+{
+ ret_code_t err_code = twi_init(p_pins_config);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom)
+{
+ /* Shift parameter val to get 2 8-bits values. */
+ uint8_t reg[3] = {write_eeprom ? MCP4725_EEPROM_ADDRESS : MCP4725_DAC_ADDRESS,
+ (val>>4), (val<<4)};
+
+ m_xfer_done = false;
+
+ ret_code_t err_code = nrf_drv_twi_tx(&m_twi, MCP4725_BASE_ADDRESS, reg, sizeof(reg), false);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ while (m_xfer_done == false);
+
+ return NRF_SUCCESS;
+}
+
+bool mcp4725_is_busy(void)
+{
+ uint8_t busy;
+ m_read_done = false;
+
+ ret_code_t err_code = nrf_drv_twi_rx(&m_twi, MCP4725_BASE_ADDRESS, &busy, sizeof(busy));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ while (m_read_done == false);
+
+ return (bool)(!(busy >> RDY_BIT_POS));
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h
new file mode 100644
index 0000000..0a71e21
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.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.
+ *
+ */
+#ifndef MCP4725_H
+#define MCP4725_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief MCP4725 digital DAC driver.
+*
+*
+* @defgroup mcp4725 MCP4725 digital DAC driver
+* @{
+* @ingroup ext_drivers
+* @brief MCP4725 digital DAC driver.
+*/
+
+typedef struct
+{
+ uint8_t scl_pin;
+ uint8_t sda_pin;
+}mcp4725_pins_config_t;
+
+/**
+ * @brief Function for setting up the driver.
+ *
+ * @param[in] p_pins_config Pointer to structere holding pins numbers to be used by TWI.
+ *
+ * @return Values returned by @ref nrfx_twi_init.
+ */
+ret_code_t mcp4725_setup(mcp4725_pins_config_t const * p_pins_config);
+
+
+/**
+ * @brief Function for setting new value to DAC.
+ *
+ * @param[in] val 12-bit value. Base on it voltage is set (Vout = (val/4095) * Vcc).
+ * @param[in] write_eeprom Defines if value will be written to DAC only or to EEPROM memmory also.
+ *
+ * @return Values returned by @ref nrfx_twi_tx.
+ */
+ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom);
+
+/**
+ * @brief Function for checking if DAC is busy saving data in EEPROM.
+ *
+ * @retval true If DAC is busy.
+ * @retval false If Dac is not busy.
+ */
+bool mcp4725_is_busy(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //MCP4725_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c
new file mode 100644
index 0000000..17ff011
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 "twi_master.h"
+#include "mpu6050.h"
+
+/*lint ++flb "Enter library region" */
+
+#define ADDRESS_WHO_AM_I (0x75U) // !< WHO_AM_I register identifies the device. Expected value is 0x68.
+#define ADDRESS_SIGNAL_PATH_RESET (0x68U) // !<
+
+static const uint8_t expected_who_am_i = 0x68U; // !< Expected value to get from WHO_AM_I register.
+static uint8_t m_device_address; // !< Device address in bits [7:1]
+
+bool mpu6050_init(uint8_t device_address)
+{
+ bool transfer_succeeded = true;
+
+ m_device_address = (uint8_t)(device_address << 1);
+
+ // Do a reset on signal paths
+ uint8_t reset_value = 0x04U | 0x02U | 0x01U; // Resets gyro, accelerometer and temperature sensor signal paths.
+ transfer_succeeded &= mpu6050_register_write(ADDRESS_SIGNAL_PATH_RESET, reset_value);
+
+ // Read and verify product ID
+ transfer_succeeded &= mpu6050_verify_product_id();
+
+ return transfer_succeeded;
+}
+
+bool mpu6050_verify_product_id(void)
+{
+ uint8_t who_am_i;
+
+ if (mpu6050_register_read(ADDRESS_WHO_AM_I, &who_am_i, 1))
+ {
+ if (who_am_i != expected_who_am_i)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool mpu6050_register_write(uint8_t register_address, uint8_t value)
+{
+ uint8_t w2_data[2];
+
+ w2_data[0] = register_address;
+ w2_data[1] = value;
+ return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
+}
+
+bool mpu6050_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
+{
+ bool transfer_succeeded;
+ transfer_succeeded = twi_master_transfer(m_device_address, &register_address, 1, TWI_DONT_ISSUE_STOP);
+ transfer_succeeded &= twi_master_transfer(m_device_address|TWI_READ_BIT, destination, number_of_bytes, TWI_ISSUE_STOP);
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h
new file mode 100644
index 0000000..f5d8d0c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef MPU6050_H
+#define MPU6050_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief MPU6050 gyro/accelerometer driver.
+*
+*
+* @defgroup nrf_drivers_mpu6050 MPU6050 gyro/accelerometer driver
+* @{
+* @ingroup ext_drivers
+* @brief MPU6050 gyro/accelerometer driver.
+*/
+
+/**
+ * @brief Function for initializing MPU6050 and verifies it's on the bus.
+ *
+ * @param device_address Device TWI address in bits [6:0].
+ * @return
+ * @retval true MPU6050 found on the bus and ready for operation.
+ * @retval false MPU6050 not found on the bus or communication failure.
+ */
+bool mpu6050_init(uint8_t device_address);
+
+/**
+ @brief Function for writing a MPU6050 register contents over TWI.
+ @param[in] register_address Register address to start writing to
+ @param[in] value Value to write to register
+ @retval true Register write succeeded
+ @retval false Register write failed
+*/
+bool mpu6050_register_write(uint8_t register_address, const uint8_t value);
+
+/**
+ @brief Function for reading MPU6050 register contents over TWI.
+ Reads one or more consecutive registers.
+ @param[in] register_address Register address to start reading from
+ @param[in] number_of_bytes Number of bytes to read
+ @param[out] destination Pointer to a data buffer where read data will be stored
+ @retval true Register read succeeded
+ @retval false Register read failed
+*/
+bool mpu6050_register_read(uint8_t register_address, uint8_t *destination, uint8_t number_of_bytes);
+
+/**
+ @brief Function for reading and verifying MPU6050 product ID.
+ @retval true Product ID is what was expected
+ @retval false Product ID was not what was expected
+*/
+bool mpu6050_verify_product_id(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MPU6050_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c
new file mode 100644
index 0000000..af73cd1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c
@@ -0,0 +1,305 @@
+/**
+ * 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.
+ *
+ */
+#include "nrf6350.h"
+#include "nrf_delay.h"
+#include "twi_master.h"
+
+/*lint ++flb "Enter library region" */
+
+#define DDRAM_ADR 0x80 //!< Write to DDRAM AC
+#define DDRAM_WR 0x40 //!< Write to DDRAM
+#define FUNC_SET 0x00 //!< Enter LCD Function settings
+#define LCD_ADDR 0x3E //!< LCD display adr
+#define JS_ADDR 0x3F //!< Joystick adr
+
+#define X 0 //!< X direction in pos 0 of joystick array
+#define Y 1 //!< Y direction in pos 1 of joystick array
+
+
+//static void nrf6350_nrf6350_lcd_set_instruction(uint8_t instr);
+
+#define BUF_LEN 32 //!< LCD data buffer length
+static uint8_t data_buffer[BUF_LEN]; //!< LCD data buffer
+static uint8_t empty_str[18] = {DDRAM_WR, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; //!< Blank line
+
+
+static bool nrf6350_lcd_set_instruction(uint8_t instr)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = instr;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_clear(void)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = (uint8_t)(DDRAM_ADR + LCD_UPPER_LINE);
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18, TWI_ISSUE_STOP))
+ {
+ return false;
+ }
+ data_buffer[1] = DDRAM_ADR + LCD_LOWER_LINE;
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18, TWI_ISSUE_STOP))
+ return false;
+ return true;
+}
+
+bool nrf6350_lcd_set_contrast(uint8_t contrast)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = 0x70 | contrast;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_on(void)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = 0x0C;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_off(void)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = 0x08;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_init(void)
+{
+ if (!twi_master_init())
+ {
+ return false;
+ }
+
+ // Sometimes the first command doesn't get through, so we'll try
+ // sending non-important "wake up" command first and don't care if it fails.
+ (void)nrf6350_lcd_wake_up();
+
+ if (!nrf6350_lcd_set_instruction(0x38)) // Function set.
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x39)) // Choose two-line mode.
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x14)) // Internal OSC frequency.
+ return false;
+ if (!nrf6350_lcd_set_contrast(LCD_CONTRAST_HIGH)) // Contrast set (low byte).
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x5F)) // Power/ICON control/.
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x6A)) // Follower control.
+ return false;
+ nrf_delay_us(200000); // Need to wait 200ms here according to datasheet.
+ if (!nrf6350_lcd_on()) // Display ON.
+ return false;
+ if (!nrf6350_lcd_clear()) // Clear display.
+ return false;
+ return nrf6350_lcd_set_instruction(0x06); // Entry mode set.
+}
+
+bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos)
+{
+ uint8_t i;
+
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = DDRAM_ADR + (pos + line);
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18 - pos, TWI_ISSUE_STOP))
+ return false;
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = DDRAM_ADR + (pos + line);
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ data_buffer[0] = DDRAM_WR;
+ for (i=0;i<size;i++)
+ {
+ if (i == LCD_LLEN)
+ break;
+ data_buffer[i + 1] = (uint8_t) * p_text++;
+ }
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, i + 1, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_js_get_value(int8_t * val)
+{
+ uint8_t js_data;
+
+ if (!twi_master_transfer(JS_ADDR << 1 | TWI_READ_BIT, data_buffer, 1, TWI_ISSUE_STOP))
+ return false;
+ js_data = (~data_buffer[0] & 0x1D); // Select the useful bits.
+
+ if ((js_data & 0x01) != 0) // Check joystick position.
+ {
+ val[X] = -1;
+ }
+ else if ((js_data & 0x10) != 0)
+ {
+ val[X] = 1;
+ }
+ else
+ {
+ val[X] = 0;
+ }
+
+ if ((js_data & 0x04) != 0)
+ {
+ val[Y] = 1;
+ }
+ else if ((js_data & 0x08) != 0)
+ {
+ val[Y] = -1;
+ }
+ else
+ {
+ val[Y] = 0;
+ }
+ return true;
+}
+
+
+bool nrf6350_js_get_status(uint8_t * js_state)
+{
+ uint8_t js_data;
+
+ if (!twi_master_transfer(JS_ADDR << 1 | TWI_READ_BIT, &js_data, 1, TWI_ISSUE_STOP))
+ {
+ return false;
+ }
+ js_data = ~js_data;
+ *js_state = js_data & 0x1F;
+ return true;
+}
+
+/** @brief First time communication with the development kit nRF6350 display will fail, this
+ * returns false on timeout instead of attempting to recover.
+ */
+static bool nrf6350_lcd_write_without_recovery(uint8_t * data,
+ uint8_t data_length,
+ bool issue_stop_condition)
+{
+ uint32_t timeout = 20000; /* max loops to wait for EVENTS_TXDSENT event*/
+
+ if (data_length == 0)
+ {
+ /* Return false for requesting data of size 0 */
+ return false;
+ }
+
+ NRF_TWI1->TXD = *data++;
+ NRF_TWI1->TASKS_STARTTX = 1;
+
+ /** @snippet [TWI HW master write] */
+ while (true)
+ {
+ while (NRF_TWI1->EVENTS_TXDSENT == 0 && (--timeout))
+ {
+ // Do nothing.
+ }
+
+ if (timeout == 0)
+ {
+ NRF_TWI1->EVENTS_STOPPED = 0;
+ NRF_TWI1->TASKS_STOP = 1;
+
+ /* Wait until stop sequence is sent */
+ while (NRF_TWI1->EVENTS_STOPPED == 0)
+ {
+ // Do nothing.
+ }
+
+ /* Timeout before receiving event*/
+ return false;
+ }
+
+ NRF_TWI1->EVENTS_TXDSENT = 0;
+ if (--data_length == 0)
+ {
+ break;
+ }
+
+ NRF_TWI1->TXD = *data++;
+ }
+ /** @snippet [TWI HW master write] */
+
+ if (issue_stop_condition)
+ {
+ NRF_TWI1->EVENTS_STOPPED = 0;
+ NRF_TWI1->TASKS_STOP = 1;
+
+ /* Wait until stop sequence is sent */
+ while (NRF_TWI1->EVENTS_STOPPED == 0)
+ {
+ // Do nothing.
+ }
+ }
+ return true;
+}
+
+/** @brief Function for transfer by twi_master.
+ */
+bool nrf6350_lcd_wake_up(void)
+{
+ uint8_t address = (LCD_ADDR << 1);
+ uint8_t dummy_data[] = {0, 0, 0, 0};
+ uint8_t dummy_data_length = 4;
+ bool issue_stop_condition = 0;
+ bool transfer_succeeded = false;
+
+ NRF_TWI1->ADDRESS = (address >> 1);
+
+ transfer_succeeded = nrf6350_lcd_write_without_recovery(dummy_data,
+ dummy_data_length,
+ issue_stop_condition);
+
+ NRF_TWI1->EVENTS_ERROR = 0;
+
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h
new file mode 100644
index 0000000..09af87e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h
@@ -0,0 +1,154 @@
+/**
+ * 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.
+ *
+ */
+#ifndef NRF6350_H_
+#define NRF6350_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LCD_LLEN 16 //!< LCD Line length
+
+#define JS_BUTTON_NONE 0x00 //!< Joystick not touched
+#define JS_BUTTON_LEFT 0x01 //!< joystick pulled left
+#define JS_BUTTON_PUSH 0x02 //!< joystick pushed
+#define JS_BUTTON_DOWN 0x04 //!< joystick pulled down
+#define JS_BUTTON_UP 0x08 //!< joystick pulled up
+#define JS_BUTTON_RIGHT 0x10 //!< joystick pulled right
+#define LCD_UPPER_LINE 0x00 //!< LCD upper line
+#define LCD_LOWER_LINE 0x40 //!< LCD lower line
+#define LCD_CONTRAST_LOW 0x00 //!< LCD Low contrast
+#define LCD_CONTRAST_MEDIUM 0x02 //!< LCD Medium contrast
+#define LCD_CONTRAST_HIGH 0x08 //!< LCD High contrast
+
+
+/**
+ * @brief Function for initializing the LCD display prior to writing.
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_init(void);
+
+/**
+ * @brief Function for writing a text string on the LCD-display.
+ *
+ * @param p_text A pointer to the text string to be written
+ * @param size Size of the text string to be written
+ * @param line The line the text should be written to
+ * @param pos The start position of the text on the line
+ * @return
+ * @retval true Write succeeded
+ * @retval false Write failed
+ */
+bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos);
+
+/**
+ * @brief Function for clearing the contents of the LCD-display.
+ *
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_clear(void);
+
+/**
+ * @brief Function for adjusting the contrast of the LCD-display, select between
+ * LCD_CONTRAST_LOW, LCD_CONTRAST_MEDIUM and LCD_CONTRAST_HIGH.
+ *
+ * @param contrast The desired contrast of the lcd display
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_set_contrast(uint8_t contrast);
+
+/**
+ * @brief Function for turning ON the LCD-display.
+ *
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_on(void);
+
+/**
+ * @brief Function for turning OFF the LCD-display.
+ *
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_off(void);
+
+/**
+ * @brief Function for getting the position of the joystick.
+ *
+ * @param val pointer to a 2 byte array where the X,Y position is stored
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_js_get_value(int8_t *val);
+
+/**
+ * @brief Function for getting the status of the joystick.
+ *
+ * @param js_state pointer to a uint8_t that receives the status of the joystick
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_js_get_status(uint8_t *js_state);
+
+/** @brief Function for transferring data over TWI bus. Used the first time you want to communicate nRF6350 to bypass a fail.
+ */
+bool nrf6350_lcd_wake_up(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF6350_H_
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c
new file mode 100644
index 0000000..8821525
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c
@@ -0,0 +1,474 @@
+/**
+ * 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(ST7735)
+
+#include "nrf_lcd.h"
+#include "nrf_drv_spi.h"
+#include "nrf_delay.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+
+// Set of commands described in ST7735 data sheet.
+#define ST7735_NOP 0x00
+#define ST7735_SWRESET 0x01
+#define ST7735_RDDID 0x04
+#define ST7735_RDDST 0x09
+
+#define ST7735_SLPIN 0x10
+#define ST7735_SLPOUT 0x11
+#define ST7735_PTLON 0x12
+#define ST7735_NORON 0x13
+
+#define ST7735_INVOFF 0x20
+#define ST7735_INVON 0x21
+#define ST7735_DISPOFF 0x28
+#define ST7735_DISPON 0x29
+#define ST7735_CASET 0x2A
+#define ST7735_RASET 0x2B
+#define ST7735_RAMWR 0x2C
+#define ST7735_RAMRD 0x2E
+
+#define ST7735_PTLAR 0x30
+#define ST7735_COLMOD 0x3A
+#define ST7735_MADCTL 0x36
+
+#define ST7735_FRMCTR1 0xB1
+#define ST7735_FRMCTR2 0xB2
+#define ST7735_FRMCTR3 0xB3
+#define ST7735_INVCTR 0xB4
+#define ST7735_DISSET5 0xB6
+
+#define ST7735_PWCTR1 0xC0
+#define ST7735_PWCTR2 0xC1
+#define ST7735_PWCTR3 0xC2
+#define ST7735_PWCTR4 0xC3
+#define ST7735_PWCTR5 0xC4
+#define ST7735_VMCTR1 0xC5
+
+#define ST7735_RDID1 0xDA
+#define ST7735_RDID2 0xDB
+#define ST7735_RDID3 0xDC
+#define ST7735_RDID4 0xDD
+
+#define ST7735_PWCTR6 0xFC
+
+#define ST7735_GMCTRP1 0xE0
+#define ST7735_GMCTRN1 0xE1
+
+#define ST7735_MADCTL_MY 0x80
+#define ST7735_MADCTL_MX 0x40
+#define ST7735_MADCTL_MV 0x20
+#define ST7735_MADCTL_ML 0x10
+#define ST7735_MADCTL_RGB 0x00
+#define ST7735_MADCTL_BGR 0x08
+#define ST7735_MADCTL_MH 0x04
+/* @} */
+
+#define RGB2BGR(x) (x << 11) | (x & 0x07E0) | (x >> 11)
+
+static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ST7735_SPI_INSTANCE); /**< SPI instance. */
+
+/**
+ * @brief Structure holding ST7735 controller basic parameters.
+ */
+typedef struct
+{
+ uint8_t tab_color; /**< Color of tab attached to the used screen. */
+}st7735_t;
+
+/**
+ * @brief Enumerator with TFT tab colors.
+ */
+typedef enum{
+ INITR_GREENTAB = 0, /**< Green tab. */
+ INITR_REDTAB, /**< Red tab. */
+ INITR_BLACKTAB, /**< Black tab. */
+ INITR_144GREENTAB /**< Green tab, 1.44" display. */
+}st7735_tab_t;
+
+static st7735_t m_st7735;
+
+static inline void spi_write(const void * data, size_t size)
+{
+ APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0));
+}
+
+static inline void write_command(uint8_t c)
+{
+ nrf_gpio_pin_clear(ST7735_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static inline void write_data(uint8_t c)
+{
+ nrf_gpio_pin_set(ST7735_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static void set_addr_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
+{
+ ASSERT(x0 <= x1);
+ ASSERT(y0 <= y1);
+
+ write_command(ST7735_CASET);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(x0);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(x1);
+ write_command(ST7735_RASET);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(y0);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(y1);
+ write_command(ST7735_RAMWR);
+}
+
+static void command_list(void)
+{
+ write_command(ST7735_SWRESET);
+ nrf_delay_ms(150);
+ write_command(ST7735_SLPOUT);
+ nrf_delay_ms(500);
+
+ write_command(ST7735_FRMCTR1);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+ write_command(ST7735_FRMCTR2);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+ write_command(ST7735_FRMCTR3);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+
+ write_command(ST7735_INVCTR);
+ write_data(0x07);
+
+ write_command(ST7735_PWCTR1);
+ write_data(0xA2);
+ write_data(0x02);
+ write_data(0x84);
+ write_command(ST7735_PWCTR2);
+ write_data(0xC5);
+ write_command(ST7735_PWCTR3);
+ write_data(0x0A);
+ write_data(0x00);
+ write_command(ST7735_PWCTR3);
+ write_data(0x8A);
+ write_data(0x2A);
+ write_command(ST7735_PWCTR5);
+ write_data(0x8A);
+ write_data(0xEE);
+ write_data(0x0E);
+
+ write_command(ST7735_INVOFF);
+ write_command(ST7735_MADCTL);
+ write_data(0xC8);
+
+ write_command(ST7735_COLMOD);
+ write_data(0x05);
+
+ if (m_st7735.tab_color == INITR_GREENTAB)
+ {
+ write_command(ST7735_CASET);
+ write_data(0x00);
+ write_data(0x02);
+ write_data(0x00);
+ write_data(0x81);
+ write_command(ST7735_RASET);
+ write_data(0x00);
+ write_data(0x01);
+ write_data(0x00);
+ write_data(0xA0);
+ }
+ else if (m_st7735.tab_color == INITR_144GREENTAB)
+ {
+ write_command(ST7735_CASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x7F);
+ write_command(ST7735_RASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x7F);
+ }
+ else if (m_st7735.tab_color == INITR_REDTAB)
+ {
+ write_command(ST7735_CASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x7F);
+ write_command(ST7735_RASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x9F);
+ }
+
+ write_command(ST7735_GMCTRP1);
+ write_data(0x02);
+ write_data(0x1c);
+ write_data(0x07);
+ write_data(0x12);
+ write_data(0x37);
+ write_data(0x32);
+ write_data(0x29);
+ write_data(0x2d);
+ write_data(0x29);
+ write_data(0x25);
+ write_data(0x2b);
+ write_data(0x39);
+ write_data(0x00);
+ write_data(0x01);
+ write_data(0x03);
+ write_data(0x10);
+ write_command(ST7735_GMCTRN1);
+ write_data(0x03);
+ write_data(0x1d);
+ write_data(0x07);
+ write_data(0x06);
+ write_data(0x2e);
+ write_data(0x2c);
+ write_data(0x29);
+ write_data(0x2d);
+ write_data(0x2e);
+ write_data(0x2e);
+ write_data(0x37);
+ write_data(0x3f);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x02);
+ write_data(0x10);
+
+ write_command(ST7735_NORON);
+ nrf_delay_ms(10);
+ write_command(ST7735_DISPON);
+ nrf_delay_ms(100);
+
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_command(ST7735_MADCTL);
+ write_data(0xC0);
+ }
+}
+
+
+static ret_code_t hardware_init(void)
+{
+ ret_code_t err_code;
+
+ nrf_gpio_cfg_output(ST7735_DC_PIN);
+
+ nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
+
+ spi_config.sck_pin = ST7735_SCK_PIN;
+ spi_config.miso_pin = ST7735_MISO_PIN;
+ spi_config.mosi_pin = ST7735_MOSI_PIN;
+ spi_config.ss_pin = ST7735_SS_PIN;
+
+ err_code = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL);
+ return err_code;
+}
+
+static ret_code_t st7735_init(void)
+{
+ ret_code_t err_code;
+
+ m_st7735.tab_color = ST7735_TAB_COLOR;
+
+ err_code = hardware_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ command_list();
+
+ return err_code;
+}
+
+static void st7735_uninit(void)
+{
+ nrf_drv_spi_uninit(&spi);
+}
+
+static void st7735_pixel_draw(uint16_t x, uint16_t y, uint32_t color)
+{
+ set_addr_window(x, y, x, y);
+
+ color = RGB2BGR(color);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ST7735_DC_PIN);
+
+ spi_write(data, sizeof(data));
+
+ nrf_gpio_pin_clear(ST7735_DC_PIN);
+}
+
+static void st7735_rect_draw(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color)
+{
+ set_addr_window(x, y, x + width - 1, y + height - 1);
+
+ color = RGB2BGR(color);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ST7735_DC_PIN);
+
+ // Duff's device algorithm for optimizing loop.
+ uint32_t i = (height * width + 7) / 8;
+
+/*lint -save -e525 -e616 -e646 */
+ switch ((height * width) % 8) {
+ case 0:
+ do {
+ spi_write(data, sizeof(data));
+ case 7:
+ spi_write(data, sizeof(data));
+ case 6:
+ spi_write(data, sizeof(data));
+ case 5:
+ spi_write(data, sizeof(data));
+ case 4:
+ spi_write(data, sizeof(data));
+ case 3:
+ spi_write(data, sizeof(data));
+ case 2:
+ spi_write(data, sizeof(data));
+ case 1:
+ spi_write(data, sizeof(data));
+ } while (--i > 0);
+ default:
+ break;
+ }
+/*lint -restore */
+ nrf_gpio_pin_clear(ST7735_DC_PIN);
+}
+
+static void st7735_dummy_display(void)
+{
+ /* No implementation needed. */
+}
+
+static void st7735_rotation_set(nrf_lcd_rotation_t rotation)
+{
+ write_command(ST7735_MADCTL);
+ switch (rotation) {
+ case NRF_LCD_ROTATE_0:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MY | ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MY | ST7735_MADCTL_BGR);
+ }
+ break;
+ case NRF_LCD_ROTATE_90:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_BGR);
+ }
+ break;
+ case NRF_LCD_ROTATE_180:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_BGR);
+ }
+ break;
+ case NRF_LCD_ROTATE_270:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MV | ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MV | ST7735_MADCTL_BGR);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void st7735_display_invert(bool invert)
+{
+ write_command(invert ? ST7735_INVON : ST7735_INVOFF);
+}
+
+static lcd_cb_t st7735_cb = {
+ .height = ST7735_HEIGHT,
+ .width = ST7735_WIDTH
+};
+
+const nrf_lcd_t nrf_lcd_st7735 = {
+ .lcd_init = st7735_init,
+ .lcd_uninit = st7735_uninit,
+ .lcd_pixel_draw = st7735_pixel_draw,
+ .lcd_rect_draw = st7735_rect_draw,
+ .lcd_display = st7735_dummy_display,
+ .lcd_rotation_set = st7735_rotation_set,
+ .lcd_display_invert = st7735_display_invert,
+ .p_lcd_cb = &st7735_cb
+};
+
+#endif // NRF_MODULE_ENABLED(ST7735)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c
new file mode 100644
index 0000000..03ac91a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c
@@ -0,0 +1,1002 @@
+/**
+ * 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 "sx1509b.h"
+
+static sx1509b_instance_t * m_p_instances;
+static uint8_t m_max_instance_count;
+static uint8_t m_inst_count;
+
+#define RETURN_IF_ERR(_err) \
+ if (_err != NRF_SUCCESS)\
+ { \
+ return _err; \
+ }
+
+/**
+ * ===============================================================================================
+ * @brief General expander utility functions.
+ */
+
+void sx1509b_init(sx1509b_instance_t * p_instances, uint8_t count)
+{
+ ASSERT(p_instances != NULL);
+ m_p_instances = p_instances;
+ m_max_instance_count = count;
+ m_inst_count = 0;
+}
+
+static void sx1509b_default_cfg_set(uint8_t instance_num)
+{
+ m_p_instances[instance_num].start_addr = 0x00;
+ for (uint8_t i = SX1509B_REG_INPUT_DISABLE_B; i < SX1509B_REG_DIR_B; i++)
+ {
+ m_p_instances[instance_num].registers[i] = 0;
+ }
+ for (uint8_t i = SX1509B_REG_DIR_B; i < SX1509B_REG_SENSE_H_B; i++)
+ {
+ m_p_instances[instance_num].registers[i] = 0xFF;
+ }
+ for (uint8_t i = SX1509B_REG_SENSE_H_B; i < SX1509B_REG_KEY_DATA_1; i++)
+ {
+ m_p_instances[instance_num].registers[i] = 0;
+ }
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_1] = 0xFF;
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_2] = 0xFF;
+ m_p_instances[instance_num].registers[SX1509B_REG_MISC] = 0x01;
+ m_p_instances[instance_num].high_input[0] = 0;
+ m_p_instances[instance_num].high_input[1] = 0;
+
+}
+ret_code_t sx1509b_add_instance(nrf_twi_sensor_t * p_twi_sensor,
+ uint8_t sensor_address)
+{
+ ASSERT(p_twi_sensor != NULL);
+ if (m_p_instances == NULL)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+ if (m_inst_count >= m_max_instance_count)
+ {
+ return NRF_ERROR_STORAGE_FULL;
+ }
+ m_p_instances[m_inst_count].p_sensor_data = p_twi_sensor;
+ m_p_instances[m_inst_count].sensor_addr = sensor_address;
+ sx1509b_default_cfg_set(m_inst_count);
+ m_inst_count++;
+ ret_code_t err_code = sx1509b_cfg_write(m_inst_count - 1);
+
+ return err_code;
+}
+
+ret_code_t sx1509b_cfg_write(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ ret_code_t err = nrf_twi_sensor_reg_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ SX1509B_REG_HIGH_INPUT_B,
+ m_p_instances[instance_num].high_input,
+ 2);
+ RETURN_IF_ERR(err);
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ &m_p_instances[instance_num].start_addr,
+ SX1509B_REG_COUNT + 1,
+ false);
+}
+
+ret_code_t sx1509b_cfg_read(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ ret_code_t err = nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ SX1509B_REG_HIGH_INPUT_B,
+ NULL,
+ m_p_instances[instance_num].high_input,
+ 2);
+ RETURN_IF_ERR(err);
+ return nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ m_p_instances[instance_num].start_addr,
+ NULL,
+ m_p_instances[instance_num].registers,
+ SX1509B_REG_COUNT);
+}
+
+ret_code_t sx1509b_clock_set(uint8_t instance_num, sx1509b_clock_t source, bool oscio_set, uint8_t oscio_freq)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t * p_reg_val = &m_p_instances[instance_num].registers[SX1509B_REG_CLOCK];
+
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_OSC_SRC_MASK, SX1509B_OSC_SRC_POS, source);
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_OSCIO_PIN_MASK, SX1509B_OSCIO_PIN_POS, oscio_set);
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val,
+ SX1509B_OSCOUT_FREQ_MASK,
+ SX1509B_OSCOUT_FREQ_POS,
+ oscio_freq);
+
+ uint8_t send_msg[] = {
+ SX1509B_REG_CLOCK,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_misc_set(uint8_t instance_num,
+ bool nreset_func,
+ sx1509b_debounce_t debounce_time,
+ bool autoclear_nint)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t * p_reg_val = &m_p_instances[instance_num].registers[SX1509B_REG_MISC];
+
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_NRESET_PIN_MASK, SX1509B_NRESET_PIN_POS, nreset_func);
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val,
+ SX1509B_AUTO_CLEAR_NINT_MASK,
+ SX1509B_AUTO_CLEAR_NINT_POS,
+ autoclear_nint);
+ uint8_t send_msg[] = {
+ SX1509B_REG_MISC,
+ *p_reg_val
+ };
+ ret_code_t err = nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ RETURN_IF_ERR(err);
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_CONFIG] = debounce_time;
+ send_msg[0] = SX1509B_REG_DEBOUNCE_CONFIG;
+ send_msg[1] = debounce_time;
+
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+}
+
+ret_code_t sx1509b_sw_reset(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t send_msg[] = {
+ SX1509B_REG_SW_RESET,
+ SX1509B_INNER_RESET_BYTE1
+ };
+ ret_code_t err = nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ RETURN_IF_ERR(err);
+ send_msg[1] = SX1509B_INNER_RESET_BYTE2;
+ err = nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ RETURN_IF_ERR(err);
+ sx1509b_default_cfg_set(instance_num);
+ return err;
+}
+
+ret_code_t sx1509b_pin_cfg_reg_set(sx1509b_registers_t reg, uint32_t pin, uint8_t set)
+{
+ if (pin >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = pin / SX1509B_INNER_PIN_COUNT;
+ pin %= SX1509B_INNER_PIN_COUNT;
+ uint8_t * p_reg_val;
+
+ uint8_t reg_addr = reg;
+ uint32_t mask = 1;
+ if (reg_addr == SX1509B_REG_LEVEL_SHIFTER_1)
+ {
+ mask = 3; // Level shifter register parameter is 2 bits long.
+ pin %= SX1509B_INNER_NEXT_BANK;
+ pin *= 2;
+ }
+ if (reg_addr == SX1509B_REG_SENSE_H_B)
+ {
+ reg_addr += 3 - (pin / SX1509B_INNER_SENSE_REG_NUM); // Setting correct sense register
+ pin %= SX1509B_INNER_SENSE_REG_NUM;
+ pin *= 2; // Multiplying by 2 to make space for 2 bits.
+ mask = 3; // Sense register parameter is 2 bits long.
+ }
+ else
+ {
+ if (pin >= SX1509B_INNER_NEXT_BANK)
+ {
+ reg_addr = reg;
+ pin -= SX1509B_INNER_NEXT_BANK;
+ }
+ else
+ {
+ reg_addr = reg + 1; // Moving to bank A registers
+
+ }
+ }
+
+ p_reg_val = &m_p_instances[inst_num].registers[reg_addr];
+
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, (mask<<pin), pin, set);
+ uint8_t send_msg[] = {
+ reg_addr,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+uint8_t sx1509b_pin_cfg_reg_get(sx1509b_registers_t reg, uint32_t pin)
+{
+ if (pin >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return 0xFF;
+ }
+
+ uint8_t inst_num = pin / SX1509B_INNER_PIN_COUNT;
+ pin %= SX1509B_INNER_PIN_COUNT;
+ uint8_t * p_reg_val;
+ uint8_t reg_addr = reg;
+ uint8_t mask = 1;
+ if (reg_addr == SX1509B_REG_LEVEL_SHIFTER_1)
+ {
+ mask = 3; // Level shifter register parameter is 2 bits long.
+ pin %= SX1509B_INNER_NEXT_BANK;
+ pin *= 2;
+ }
+ if (reg_addr >= SX1509B_REG_SENSE_H_B && reg_addr <= SX1509B_REG_SENSE_L_A)
+ {
+ reg_addr += 3 - (pin / SX1509B_INNER_SENSE_REG_NUM); // Setting correct sense register
+ pin %= SX1509B_INNER_SENSE_REG_NUM;
+ pin *= 2; // Multiplying by 2 to make space for 2 bits.
+ mask = 3; // Sense register parameter is 2 bits long.
+ }
+ else
+ {
+ reg_addr += (pin >= SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin %= SX1509B_INNER_NEXT_BANK;
+ }
+ p_reg_val = &m_p_instances[inst_num].registers[reg_addr];
+
+ return NRF_TWI_SENSOR_REG_VAL_GET(*p_reg_val,(mask<<pin),pin);
+}
+
+ret_code_t sx1509b_port_cfg_reg_set(sx1509b_registers_t reg,
+ uint32_t port,
+ uint8_t mask,
+ sx1509b_port_op_t flag)
+{
+ if (port >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = port / SX1509B_INNER_PORT_COUNT;
+ port %= SX1509B_INNER_PORT_COUNT;
+ uint8_t reg_addr = reg + !port;
+
+ uint8_t * reg_val = &m_p_instances[inst_num].registers[reg_addr];
+
+ switch (flag)
+ {
+ case SX1509B_PORT_WRITE:
+ *reg_val = mask;
+ break;
+ case SX1509B_PORT_CLEAR:
+ *reg_val &= ~mask;
+ break;
+ case SX1509B_PORT_SET:
+ *reg_val |= mask;
+ break;
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t send_msg[] = {
+ reg_addr,
+ *reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data, m_p_instances[inst_num].sensor_addr, send_msg, ARRAY_SIZE(send_msg), true);
+}
+
+uint8_t sx1509b_port_cfg_reg_get(sx1509b_registers_t reg, uint32_t port)
+{
+ if (port >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return 0;
+ }
+
+ uint8_t inst_num = port / SX1509B_INNER_PORT_COUNT;
+ port %= SX1509B_INNER_PORT_COUNT;
+ uint8_t reg_addr = reg + !port;
+ return m_p_instances[inst_num].registers[reg_addr];
+}
+
+ret_code_t sx1509b_pin_data_update(nrf_twi_sensor_reg_cb_t user_cb)
+{
+ ret_code_t err_code;
+ for (uint8_t i = 0; i < m_inst_count - 1; i++)
+ {
+ err_code = nrf_twi_sensor_reg_read(m_p_instances[i].p_sensor_data,
+ m_p_instances[i].sensor_addr,
+ SX1509B_REG_DATA_B,
+ NULL,
+ &m_p_instances[i].registers[SX1509B_REG_DATA_B],
+ 2);
+ RETURN_IF_ERR(err_code);
+ }
+ return nrf_twi_sensor_reg_read(m_p_instances[m_inst_count - 1].p_sensor_data,
+ m_p_instances[m_inst_count - 1].sensor_addr,
+ SX1509B_REG_DATA_B,
+ user_cb,
+ &m_p_instances[m_inst_count - 1].registers[SX1509B_REG_DATA_B],
+ 2);
+}
+
+ret_code_t sx1509b_pin_latch_update(nrf_twi_sensor_reg_cb_t user_cb)
+{
+ ret_code_t err_code;
+ for (uint8_t i = 0; i < m_inst_count - 1; i++) // -1 so last read triggers callback
+ {
+ err_code = nrf_twi_sensor_reg_read(m_p_instances[i].p_sensor_data,
+ m_p_instances[i].sensor_addr,
+ SX1509B_REG_INT_SRC_B,
+ NULL,
+ &m_p_instances[i].registers[SX1509B_REG_INT_SRC_B],
+ 2);
+ RETURN_IF_ERR(err_code);
+ }
+ return nrf_twi_sensor_reg_read(m_p_instances[m_inst_count - 1].p_sensor_data,
+ m_p_instances[m_inst_count - 1].sensor_addr,
+ SX1509B_REG_INT_SRC_B,
+ user_cb,
+ &m_p_instances[m_inst_count - 1].registers[SX1509B_REG_INT_SRC_B],
+ 2);
+}
+
+
+
+
+ret_code_t sx1509b_pin_high_input(uint32_t pin_number, bool set)
+{
+ if (pin_number >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg_addr;
+ uint8_t * p_reg_val;
+ if (pin_number < SX1509B_INNER_NEXT_BANK)
+ {
+ reg_addr = SX1509B_REG_HIGH_INPUT_A;
+ p_reg_val = &m_p_instances[inst_num].high_input[1];
+ }
+ else
+ {
+ reg_addr = SX1509B_REG_HIGH_INPUT_B;
+ p_reg_val = &m_p_instances[inst_num].high_input[0];
+ pin_number -= SX1509B_INNER_NEXT_BANK;
+ }
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, (1U << pin_number), pin_number, set);
+ uint8_t send_msg[] = {
+ reg_addr,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+
+ret_code_t sx1509b_port_high_input(uint8_t port_num, uint8_t out_mask, sx1509b_port_op_t flag)
+{
+ if (port_num >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = port_num / SX1509B_INNER_PORT_COUNT;
+ port_num %= SX1509B_INNER_PORT_COUNT;
+ uint8_t reg_addr = SX1509B_REG_HIGH_INPUT_B + !port_num;
+
+ uint8_t * reg_val = &m_p_instances[inst_num].high_input[!port_num];
+
+ switch (flag)
+ {
+ case SX1509B_PORT_WRITE:
+ *reg_val = out_mask;
+ break;
+ case SX1509B_PORT_CLEAR:
+ *reg_val &= ~out_mask;
+ break;
+ case SX1509B_PORT_SET:
+ *reg_val |= out_mask;
+ break;
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t send_msg[] = {
+ reg_addr,
+ *reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+}
+
+/**
+ * ===============================================================================================
+ * @brief Functions compatible with nrf_gpio
+ */
+
+
+
+ret_code_t sx1509b_pin_cfg_input(uint32_t pin_number, sx1509b_pin_pull_t pull_config)
+{
+ ret_code_t err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_DIR_B, pin_number, SX1509B_PIN_DIR_INPUT);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_INPUT_DISABLE_B, pin_number, 0);
+ RETURN_IF_ERR(err_code);
+ switch (pull_config)
+ {
+ case SX1509B_PIN_NOPULL:
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, pin_number, 0);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_UP_B, pin_number, 0);
+ break;
+ case SX1509B_PIN_PULLDOWN:
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, pin_number, 1);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_UP_B, pin_number, 0);
+ break;
+ case SX1509B_PIN_PULLUP:
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, pin_number, 0);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_UP_B, pin_number, 1);
+ break;
+ };
+ return err_code;
+}
+
+ret_code_t sx1509b_pin_cfg_default(uint32_t pin_number)
+{
+ if (pin_number >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = (pin_number >= SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+
+ ret_code_t err_code = NRF_SUCCESS;
+ for (uint8_t i = SX1509B_REG_INPUT_DISABLE_B + reg; i < SX1509B_REG_DIR_B; i += 2)
+ {
+ if (IS_SET(m_p_instances[inst_num].registers[i], pin_number) == 1)
+ {
+ CLR_BIT(m_p_instances[inst_num].registers[i], pin_number);
+ err_code = nrf_twi_sensor_reg_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ i,
+ &m_p_instances[inst_num].registers[i],
+ 1);
+ }
+ }
+ for (uint8_t i = SX1509B_REG_DIR_B + reg; i < SX1509B_REG_SENSE_H_B; i += 2)
+ {
+ if (IS_SET(m_p_instances[inst_num].registers[i], pin_number) == 0)
+ {
+ SET_BIT(m_p_instances[inst_num].registers[i], pin_number);
+ err_code = nrf_twi_sensor_reg_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ i,
+ &m_p_instances[inst_num].registers[i],
+ 1);
+ }
+ }
+ for (uint8_t i = SX1509B_REG_SENSE_H_B + reg; i < SX1509B_REG_KEY_DATA_1; i += 2)
+ {
+ if (IS_SET(m_p_instances[inst_num].registers[i], pin_number) == 1)
+ {
+ CLR_BIT(m_p_instances[inst_num].registers[i], pin_number);
+ err_code = nrf_twi_sensor_reg_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ i,
+ &m_p_instances[inst_num].registers[i],
+ 1);
+ }
+ }
+ return err_code;
+}
+
+ret_code_t sx1509b_pin_cfg_sense_input(uint32_t pin_number,
+ sx1509b_pin_pull_t pull_config,
+ sx1509b_pin_sense_t sense_config)
+{
+ ret_code_t err_code = sx1509b_pin_cfg_input(pin_number, pull_config);
+ RETURN_IF_ERR(err_code);
+ return sx1509b_pin_cfg_sense_set(pin_number, sense_config);
+}
+
+
+ret_code_t sx1509b_pin_cfg_sense_set(uint32_t pin_number, sx1509b_pin_sense_t sense_config)
+{
+ ret_code_t err;
+ if (sense_config == SX1509B_PIN_NOSENSE)
+ {
+ err = sx1509b_pin_cfg_reg_set(SX1509B_REG_INT_MASK_B, pin_number, 1);
+ RETURN_IF_ERR(err);
+ }
+ else
+ {
+ err = sx1509b_pin_cfg_reg_set(SX1509B_REG_INT_MASK_B, pin_number, 0);
+ RETURN_IF_ERR(err);
+ }
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_SENSE_H_B, pin_number, sense_config);
+}
+
+ret_code_t sx1509b_pin_dir_set(uint32_t pin_number, sx1509b_pin_dir_t direction)
+{
+ if (direction == SX1509B_PIN_DIR_INPUT)
+ {
+ return sx1509b_pin_cfg_input(pin_number, SX1509B_PIN_NOPULL);
+ }
+ else
+ {
+ return sx1509b_pin_cfg_output(pin_number);
+ }
+}
+
+ret_code_t sx1509b_ports_read(uint8_t start_port, uint32_t length, uint8_t * p_masks)
+{
+ if (start_port + length > SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ for (uint8_t i = 0; i < length; i++)
+ {
+ p_masks[i] = sx1509b_port_in_read(start_port + i);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t sx1509b_latches_read(uint8_t start_port, uint32_t length, uint8_t * p_masks)
+{
+ if (start_port + length > SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ for (uint8_t i = 0; i < length; i++)
+ {
+ p_masks[i] = sx1509b_port_cfg_reg_get(SX1509B_REG_INT_SRC_B, start_port + i);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t sx1509b_pin_latch_clear(uint32_t pin_number)
+{
+ ret_code_t err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_INT_SRC_B, pin_number, 1);
+ RETURN_IF_ERR(err_code);
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = SX1509B_REG_INT_SRC_B;
+ reg += (pin_number >= SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ CLR_BIT(m_p_instances[inst_num].registers[reg], pin_number);
+ return err_code;
+}
+
+/**
+ * ===============================================================================================
+ * @brief Led driver functions.
+ */
+
+ret_code_t sx1509b_led_driver_enable(uint8_t instance_num, bool clock_internal, uint8_t frequency)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_CLOCK],
+ SX1509B_OSC_SRC_MASK,
+ SX1509B_OSC_SRC_POS,
+ (clock_internal == 1) ? 2 : 1);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_MISC],
+ SX1509B_LED_FREQ_MASK,
+ SX1509B_LED_FREQ_POS,
+ frequency);
+ uint8_t send_msg[] = {
+ SX1509B_REG_CLOCK,
+ m_p_instances[instance_num].registers[SX1509B_REG_CLOCK],
+ m_p_instances[instance_num].registers[SX1509B_REG_MISC]
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_led_mode(uint8_t port_num, bool mode)
+{
+ if (port_num >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = port_num / SX1509B_INNER_PORT_COUNT;
+ port_num %= SX1509B_INNER_PORT_COUNT;
+ uint8_t *p_reg_val = &m_p_instances[inst_num].registers[SX1509B_REG_MISC];
+
+ if (port_num == 1)
+ {
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_LED_MODE_B_MASK, SX1509B_LED_MODE_B_POS, mode);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_LED_MODE_A_MASK, SX1509B_LED_MODE_A_POS, mode);
+ }
+ uint8_t send_msg[] = {
+ SX1509B_REG_MISC,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+uint8_t sx1509b_led_driver_get_reg(uint32_t pin_number)
+{
+ uint8_t reg;
+ bool fade_reg = false;
+ if (pin_number >= SX1509B_INNER_NEXT_BANK)
+ {
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ if (pin_number >= SX1509B_LED_DRIVER_TIME_REG_NUM)
+ {
+ reg = SX1509B_REG_LED_FADE_B_START;
+ fade_reg = true;
+ }
+ else
+ {
+ reg = SX1509B_REG_LED_BANK_B_START;
+ }
+ }
+ else
+ {
+ if (pin_number >= SX1509B_LED_DRIVER_TIME_REG_NUM)
+ {
+ reg = SX1509B_REG_LED_FADE_A_START;
+ fade_reg = true;
+ }
+ else
+ {
+ reg = SX1509B_REG_LED_BANK_A_START;
+ }
+ }
+
+ if (fade_reg == true)
+ {
+ pin_number %= SX1509B_LED_DRIVER_FADE_REG_NUM;
+ reg += SX1509B_LED_DRIVER_FADE_REG_LEN * pin_number;
+ }
+ else
+ {
+ pin_number %= SX1509B_LED_DRIVER_TIME_REG_NUM;
+ reg += SX1509B_LED_DRIVER_TIME_REG_LEN * pin_number;
+ }
+
+ return reg;
+}
+
+ret_code_t sx1509b_led_pin_time(uint32_t pin_number,
+ uint8_t on_time,
+ uint8_t on_intensity,
+ uint8_t off_time,
+ uint8_t off_intensity)
+{
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = sx1509b_led_driver_get_reg(pin_number);
+ uint8_t send_msg[] = {
+ reg,
+ on_time & 0x1F,
+ on_intensity,
+ (off_time << SX1509B_OFF_TIME_POS) | (off_intensity & SX1509B_OFF_INTENSITY_MASK)
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_led_pin_fade(uint32_t pin_number, uint8_t fade_in, uint8_t fade_out)
+{
+ if ((pin_number % SX1509B_INNER_NEXT_BANK) <= SX1509B_LED_DRIVER_TIME_REG_LEN)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = sx1509b_led_driver_get_reg(pin_number) + SX1509B_LED_DRIVER_T_RISE;
+ uint8_t send_msg[] = {
+ reg,
+ fade_in & 0x1F,
+ fade_out & 0x1F
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_led_pin_enable(uint32_t pin_number)
+{
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg_add = (pin_number > SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_INPUT_DISABLE_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_PULL_UP_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_OPEN_DRAIN_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DIR_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DATA_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_LED_DRV_ENABLE_B + reg_add], pin_number);
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ &m_p_instances[inst_num].start_addr,
+ SX1509B_REG_DEBOUNCE_CONFIG + 1, // + 1 byte for address
+ false);
+}
+
+ret_code_t sx1509b_led_pin_disable(uint32_t pin_number)
+{
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg_add = (pin_number > SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_INPUT_DISABLE_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_OPEN_DRAIN_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DIR_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DATA_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_LED_DRV_ENABLE_B + reg_add], pin_number);
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ &m_p_instances[inst_num].start_addr,
+ SX1509B_REG_DEBOUNCE_CONFIG + 1, // + 1 byte for address
+ false);
+}
+
+/**
+ * ===============================================================================================
+ * @brief Key Engine functions.
+ */
+ret_code_t sx1509b_key_engine_enable(uint8_t instance_num,
+ uint8_t rows,
+ uint8_t columns,
+ sx1509b_key_sleep_t sleep_time,
+ sx1509b_key_scan_t scan_time,
+ sx1509b_debounce_t debounce_time)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (rows < 2)
+ {
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2],
+ SX1509B_ROW_NUM_MASK,
+ SX1509B_ROW_NUM_POS,
+ 0);
+ uint8_t send_msg[] = {
+ SX1509B_REG_KEY_CONFIG_2,
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2]
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ }
+
+ uint8_t in_mask = 0, out_mask = 0;
+ uint8_t in_port = 0 + instance_num * SX1509B_INNER_PORT_COUNT;
+ uint8_t out_port = 1 + instance_num * SX1509B_INNER_PORT_COUNT;
+ for (uint8_t i = 0; i < rows; i++)
+ {
+ in_mask <<= 1;
+ in_mask |= 1;
+ }
+
+ for (uint8_t i = 0; i < columns; i++)
+ {
+ out_mask <<= 1;
+ out_mask |= 1;
+ }
+
+ ret_code_t err = sx1509b_port_dir_output_set(in_port, in_mask);
+ RETURN_IF_ERR(err);
+ err = sx1509b_port_dir_input_set(out_port, out_mask);
+ RETURN_IF_ERR(err);
+ err = sx1509b_port_open_drain(out_port, out_mask, SX1509B_PORT_SET);
+ RETURN_IF_ERR(err);
+ err = sx1509b_port_pull_up(in_port, in_mask, SX1509B_PORT_SET);
+ RETURN_IF_ERR(err);
+
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_CONFIG] = debounce_time;
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_EN_B] |= in_mask;
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_1],
+ SX1509B_SLEEP_TIME_MASK,
+ SX1509B_SLEEP_TIME_POS,
+ sleep_time);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_1],
+ SX1509B_SCAN_TIME_MASK,
+ SX1509B_SCAN_TIME_POS,
+ scan_time);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2],
+ SX1509B_ROW_NUM_MASK,
+ SX1509B_ROW_NUM_POS,
+ rows - 1);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2],
+ SX1509B_COL_NUM_MASK,
+ SX1509B_COL_NUM_POS,
+ columns - 1);
+ uint8_t send_msg[] = {
+ SX1509B_REG_DEBOUNCE_CONFIG,
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_CONFIG],
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_EN_B],
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_EN_A],
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_1],
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2]
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_key_data_update(uint8_t instance_num, nrf_twi_sensor_reg_cb_t user_cb)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ SX1509B_REG_KEY_DATA_1,
+ user_cb,
+ &m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_1],
+ 2);
+}
+
+static uint8_t sx1509b_key_get_bit_pos(uint8_t reg)
+{
+ uint8_t ret_val = 0xFF;
+ for(uint8_t i = 0; i < 8; i++)
+ {
+ if (IS_SET(reg, 0) == 1)
+ {
+ ret_val = i;
+ break;
+ }
+ reg >>= 1;
+ }
+ return ret_val;
+}
+
+uint8_t sx1509b_key_column_get(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t reg_val = ~m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_1];
+
+ return sx1509b_key_get_bit_pos(reg_val);
+
+}
+
+uint8_t sx1509b_key_row_get(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t reg_val = ~m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_2];
+
+ return sx1509b_key_get_bit_pos(reg_val);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h
new file mode 100644
index 0000000..2c6e828
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h
@@ -0,0 +1,1238 @@
+/**
+ * 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 SX1509B_H
+#define SX1509B_H
+
+#include "nrf_twi_sensor.h"
+#include "sx1509b_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define SX1509B_BASE_ADDRESS_FIRST 0x3Eu
+#define SX1509B_BASE_ADDRESS_SECOND 0x3Fu
+#define SX1509B_BASE_ADDRESS_THIRD 0x70u
+#define SX1509B_BASE_ADDRESS_FOURTH 0x71u
+
+/**
+ * @brief Led driver registers.
+ */
+typedef enum
+{
+ SX1509B_LED_DRIVER_T_ON,
+ SX1509B_LED_DRIVER_I_ON,
+ SX1509B_LED_DRIVER_OFF,
+ SX1509B_LED_DRIVER_T_RISE,
+ SX1509B_LED_DRIVER_T_FALL
+} sx1509b_led_driver_set_t;
+
+
+/**
+ * @brief Pin direction setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_DIR_OUTPUT,
+ SX1509B_PIN_DIR_INPUT
+} sx1509b_pin_dir_t;
+
+/**
+ * @brief Pin output setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_CLR,
+ SX1509B_PIN_SET
+} sx1509b_pin_set_t;
+
+/**
+ * @brief Pin pull setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_NOPULL,
+ SX1509B_PIN_PULLDOWN,
+ SX1509B_PIN_PULLUP
+} sx1509b_pin_pull_t;
+
+/**
+ * @brief Pin sense setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_NOSENSE,
+ SX1509B_PIN_SENSE_RISING,
+ SX1509B_PIN_SENSE_FALLING,
+ SX1509B_PIN_SENSE_BOTH
+} sx1509b_pin_sense_t;
+
+/**
+ * @brief Port operation setting.
+ *
+ * SX1509B_PORT_WRITE - mask is written to the port.
+ * SX1509B_PORT_CLEAR - positive bits in mask are cleared in port.
+ * SX1509B_PORT_SET - positive bits in mask are set in port.
+ */
+typedef enum
+{
+ SX1509B_PORT_WRITE,
+ SX1509B_PORT_CLEAR,
+ SX1509B_PORT_SET
+} sx1509b_port_op_t;
+
+/**
+ * @brief Level shifter setting.
+ */
+typedef enum
+{
+ SX1509B_LEVEL_OFF,
+ SX1509B_LEVEL_A_TO_B,
+ SX1509B_LEVEL_B_TO_A
+} sx1509b_level_shift_t;
+
+
+/**
+ * @brief Debounce settings.
+ */
+typedef enum
+{
+ SX1509B_DEBOUNCE_0_5MS,
+ SX1509B_DEBOUNCE_1MS,
+ SX1509B_DEBOUNCE_2MS,
+ SX1509B_DEBOUNCE_4MS,
+ SX1509B_DEBOUNCE_8MS,
+ SX1509B_DEBOUNCE_16MS,
+ SX1509B_DEBOUNCE_32MS,
+ SX1509B_DEBOUNCE_64MS
+} sx1509b_debounce_t;
+
+
+/**
+ * @brief Clock setting.
+ */
+typedef enum
+{
+ SX1509B_CLOCK_DISABLED,
+ SX1509B_CLOCK_EXTERNAL,
+ SX1509B_CLOCK_INTERNAL
+} sx1509b_clock_t;
+
+
+/**
+ * @brief Key engine sleep time setting.
+ */
+typedef enum
+{
+ SX1509B_KEY_TIME_SLEEP_OFF,
+ SX1509B_KEY_TIME_SLEEP_128MS,
+ SX1509B_KEY_TIME_SLEEP_256MS,
+ SX1509B_KEY_TIME_SLEEP_512MS,
+ SX1509B_KEY_TIME_SLEEP_1S,
+ SX1509B_KEY_TIME_SLEEP_2S,
+ SX1509B_KEY_TIME_SLEEP_4S,
+ SX1509B_KEY_TIME_SLEEP_8S
+} sx1509b_key_sleep_t;
+
+
+/**
+ * @brief Key engine scan time setting.
+ */
+typedef enum
+{
+ SX1509B_KEY_TIME_SCAN_1MS,
+ SX1509B_KEY_TIME_SCAN_2MS,
+ SX1509B_KEY_TIME_SCAN_4MS,
+ SX1509B_KEY_TIME_SCAN_8MS,
+ SX1509B_KEY_TIME_SCAN_16MS,
+ SX1509B_KEY_TIME_SCAN_32MS,
+ SX1509B_KEY_TIME_SCAN_64MS,
+ SX1509B_KEY_TIME_SCAN_128MS
+} sx1509b_key_scan_t;
+
+/**
+ * @brief Macro that defines expander module.
+ *
+ * @param[in] sx1509b_inst_name Name of the instance to be created.
+ * @param[in] instance_count Number of connected expanders.
+ */
+#define SX1509B_INSTANCES_DEF_START(sx1509b_inst_name, instance_count)\
+ static sx1509b_instance_t sx1509b_inst_name[instance_count]
+
+
+/**
+ * ===============================================================================================
+ * @brief General expander utility functions.
+ */
+
+/**
+ * @brief Function initialising expander module.
+ *
+ * @param[in] p_instances Pointer to expander module.
+ * @param[in] Number of connected expanders.
+ */
+void sx1509b_init(sx1509b_instance_t * p_instances, uint8_t count);
+
+/**
+ * @brief Function adding expander instance.
+ *
+ * @note Should be called for every connected expander.
+ * Order of calls define order of pins and ports.
+ *
+ * @param[in] p_twi_sensor Pointer to common sensor instance. @ref NRF_TWI_SENSOR_DEF
+ * @param[in] sensor_address Address of expander on I2C bus.
+ *
+ * @retval NRF_ERROR_MODULE_NOT_INITIALIZED Returned if expander module wasn't initialised
+ * @retval NRF_ERROR_STORAGE_FULL Returned if trying to add more instances than defined.
+ * @retval other Return error code from nrf_twi_sensor
+ * @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_add_instance(nrf_twi_sensor_t * p_twi_sensor, uint8_t sensor_address);
+
+/**
+ * @brief Function for writing current configuration to expander.
+ *
+ * @param[in] instance_num Number of expander, order is the same as sx1509b_add_instance calls.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_cfg_write(uint8_t instance_num);
+
+/**
+ * @brief Function for reading current configuration of expander.
+ *
+ * @param[in] instance_num Number of expander, order is the same as sx1509b_add_instance calls.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_cfg_read(uint8_t instance_num);
+
+/**
+ * @brief Function for setting clock configuration.
+ *
+ * @param instance_num Number of expander.
+ * @param source Clock source.
+ * @param oscio_set Oscio pin setting. True if pin is enabled.
+ * @param oscio_freq Oscio frequency divider. Refer to expander documentation.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_clock_set(uint8_t instance_num,
+ sx1509b_clock_t source,
+ bool oscio_set,
+ uint8_t oscio_freq);
+
+/*
+ * @brief Function for setting nreset and debounce time.
+ *
+ * @param instance_num Number of expander.
+ * @param nreset_func Purpose of nreset pin.
+ * @arg true Pin resets PWM/Blink/Fade counters.
+ * @arg false Pin is equivalent to POR.
+ * @param debounce_time Debounce time setting.
+ * @param autoclear_nint Autoclear nint and interrupt source registers when pin data is read.
+ * True if disabled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_misc_set(uint8_t instance_num,
+ bool nreset_func,
+ sx1509b_debounce_t debounce_time,
+ bool autoclear_nint);
+
+/**
+ * @brief Function sending software reset command to expander.
+ *
+ * @param instance_num Number of expander.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_sw_reset(uint8_t instance_num);
+
+/**
+ * @brief Function for setting register configuration of a single pin.
+ *
+ * @param[in] reg Register address, if register has two banks, address of bank B has to be used.
+ * @param[in] pin Pin number.
+ * @param[in] set Value to set.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_pin_cfg_reg_set(sx1509b_registers_t reg, uint32_t pin, uint8_t set);
+
+/**
+ * @brief Function for getting register configuration of a single pin.
+ *
+ * @param[in] reg Register address, if register has two banks, address of bank B has to be used.
+ * @param[in] pin Pin number.
+ *
+ * @retval 0xFF Returned if there is no pin with given number.
+ * @return other Pin setting value at given register.
+ */
+uint8_t sx1509b_pin_cfg_reg_get(sx1509b_registers_t reg, uint32_t pin);
+
+/**
+ * @brief Function for setting register configuration of a port.
+ *
+ * @param reg Register address, if register has two banks, address of bank B has to be used.
+ * @param port Port number.
+ * @param mask Mask for the operating.
+ * @param flag Operation, should the mask be written into register, clear values or set them.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no port with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_port_cfg_reg_set(sx1509b_registers_t reg,
+ uint32_t port,
+ uint8_t mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for getting register configuration of a port.
+ *
+ * @param reg Register address, if register has two banks, address of bank B has to be used.
+ * @param port Port number.
+ *
+ * @retval Register value.
+ */
+uint8_t sx1509b_port_cfg_reg_get(sx1509b_registers_t reg, uint32_t port);
+
+/**
+ * @brief Function for updating pin data.
+ *
+ * @param user_cb Function to be called after pin data update is done.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t sx1509b_pin_data_update(nrf_twi_sensor_reg_cb_t user_cb);
+
+/**
+ * @brief Function for updating latch data.
+ *
+ * @param user_cb Function to be called after latch update is done.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t sx1509b_pin_latch_update(nrf_twi_sensor_reg_cb_t user_cb);
+
+/**
+ * @brief Function for setting long slew for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Long slew setting.
+ * @arg true Long slew is enabled.
+ * @arg false Long slew is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_long_slew(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting low drive for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Low drive setting.
+ * @arg true Low drive is enabled.
+ * @arg false Low drive is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_low_drive(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting open drain for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Open drain setting.
+ * @arg true Open drain is enabled.
+ * @arg false Open drain is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_open_drain(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting polarity for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Polarity setting.
+ * @arg true Inverted polarity.
+ * @arg false Normal polarity.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_polarity(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting debounce for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Debounce setting.
+ * @arg true Debouncing is enabled.
+ * @arg false Debouncing is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_debounce(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting high input for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set High input setting.
+ * @arg true High input is enabled.
+ * @arg false High input is disabled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_pin_high_input(uint32_t pin_number, bool set);
+/**
+ * @brief Function for setting level shift for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Level shift setting.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_level_shifter(uint32_t pin_number,
+ sx1509b_level_shift_t set);
+
+/**
+ * @brief Function for setting longslew for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Long slew mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_long_slew(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting low drive for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Low drive mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_low_drive(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting open drain for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Open drain mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_open_drain(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting polarity for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Polarity mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_polarity(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting debounce for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Debounce mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_debounce(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting high input for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask High input mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_port_high_input(uint8_t port_num, uint8_t out_mask, sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting pull up for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Pull up mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_pull_up(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting pull down for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Pull down mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_pull_down(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * ===============================================================================================
+ * @brief Functions compatible with nrf_gpio
+ */
+
+/**
+ * @brief Function for configuring the given GPIO pin number as output, hiding inner details.
+ * This function can be used to configure a pin as simple output with gate driving.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @note Sense capability on the pin is disabled as the pins are configured as output.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_output(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input, hiding inner details.
+ * This function can be used to configure a pin as simple input.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high).
+ *
+ * @note Sense capability on the pin is disabled and input is connected to buffer.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_input(uint32_t pin_number, sx1509b_pin_pull_t pull_config);
+
+/**
+ * @brief Function for resetting pin configuration to its default state.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_default(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_watcher(uint32_t pin_number); // non
+
+/**
+ * @brief Function for disconnecting input for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_input_disconnect(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input, hiding inner details.
+ * Sense capability on the pin is configurable and input is connected to buffer.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param pull_config State of the pin pull resistor (no pull, pulled down, or pulled high).
+ * @param sense_config Sense level of the pin (no sense, sense low, sense high or sense both).
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_sense_input(uint32_t pin_number,
+ sx1509b_pin_pull_t pull_config,
+ sx1509b_pin_sense_t sense_config);
+
+/**
+ * @brief Function for configuring sense level for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param sense_config Sense configuration.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_sense_set(uint32_t pin_number, sx1509b_pin_sense_t sense_config);
+
+/**
+ * @brief Function for setting the direction for a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number for which to set the direction.
+ * @param direction Specifies the direction.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_dir_set(uint32_t pin_number, sx1509b_pin_dir_t direction);
+
+/**
+ * @brief Function for setting a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to set.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_set(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to clear.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_clear(uint32_t pin_number);
+
+/**
+ * @brief Function for toggling a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to toggle.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_toggle(uint32_t pin_number);
+
+/**
+ * @brief Function for writing a value to a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to write.
+ *
+ * @param value Specifies the value to be written to the pin.
+ * @arg 0 Clears the pin.
+ * @arg >=1 Sets the pin.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_write(uint32_t pin_number, sx1509b_pin_set_t value);
+
+/**
+ * @brief Function for reading the input level of a GPIO pin.
+ *
+ * @note The pin must have input connected for the value
+ * returned from this function to be valid.
+ * Due to specifics of TWI expander, pin data must be updated first
+ * to get current value @ref sx1509b_pin_data_update
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @return 0 if the pin input level is low. Positive value if the pin is high.
+ */
+__STATIC_INLINE uint32_t sx1509b_pin_read(uint32_t pin_number);
+
+
+
+/**
+ * @brief Function for reading the output level of a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @return 0 if the pin output level is low. Positive value if pin output is high.
+ */
+__STATIC_INLINE uint32_t sx1509b_pin_out_read(uint32_t pin_number);
+
+/**
+ * @brief Function for reading the sense configuration of a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @retval Sense configuration.
+ */
+__STATIC_INLINE sx1509b_pin_sense_t sx1509b_pin_sense_get(uint32_t pin_number);
+
+/**
+ * @brief Function for getting expander port number based on pin number.
+ *
+ * @retval Port number.
+ */
+__STATIC_INLINE uint8_t sx1509b_pin_port_decode(uint32_t pin_number);
+
+/**
+ * @brief Function for setting output direction on selected pins on a given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Mask specifying the pins to set as output.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_dir_output_set(uint8_t port_num, uint8_t out_mask);
+
+/**
+ * @brief Function for setting input direction on selected pins on a given port.
+ *
+ * @param port_num Port number.
+ * @param in_mask Mask specifying the pins to set as input.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_dir_input_set(uint8_t port_num, uint8_t in_mask);
+
+/**
+ * @brief Function for writing the direction configuration of GPIO pins in a given port.
+ *
+ * @param port_num Port number.
+ * @param dir_mask Mask specifying the direction of pins.
+ * Bit set means that the given pin is configured as output.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_dir_write(uint8_t port_num, uint8_t dir_mask);
+
+/**
+ * @brief Function for reading the direction configuration of a GPIO port.
+ *
+ * @param port_num Port number.
+ *
+ * @note Returns 0 if port doesn't exist.
+ *
+ * @retval Pin configuration of the current direction settings.
+ * Bit set means that the given pin is configured as output.
+ */
+__STATIC_INLINE uint8_t sx1509b_port_dir_read(uint8_t port_num);
+
+/**
+ * @brief Function for reading the input signals of GPIO pins on a given port.
+ *
+ * @param port_num Port number.
+ *
+ * @note Returns 0 if port doesn't exist.
+ *
+ * @retval Port input values.
+ */
+__STATIC_INLINE uint8_t sx1509b_port_in_read(uint8_t port_num);
+
+/**
+ * @brief Function for reading the output signals of GPIO pins of a given port.
+ *
+ * @param port_num Port number.
+ *
+ * @note Returns 0 if port doesn't exist.
+ *
+ * @retval Port output values.
+ */
+__STATIC_INLINE uint8_t sx1509b_port_out_read(uint8_t port_num);
+
+/**
+ * @brief Function for writing the GPIO pins output on a given port.
+ *
+ * @param port_num Port number.
+ * @param value Output port mask.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_out_write(uint8_t port_num, uint8_t value);
+
+/**
+ * @brief Function for setting high level on selected GPIO pins of a given port.
+ *
+ * @param port_num Port number.
+ * @param set_mask Mask with pins to set as logical high level.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_out_set(uint8_t port_num, uint8_t set_mask);
+
+/**
+ * @brief Function for setting low level on selected GPIO pins of a given port.
+ *
+ * @param port_num Port number.
+ * @param clr_mask Mask with pins to set as logical low level.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_out_clear(uint8_t port_num, uint8_t clr_mask);
+
+/**
+ * @brief Function for reading pins state of multiple consecutive ports.
+ *
+ * @note Due to specifics of TWI expander, pin data must be updated first
+ * to get current value @ref sx1509b_pin_data_update
+ *
+ * @param start_port Index of the first port to read.
+ * @param length Number of ports to read.
+ * @param p_masks Pointer to output array where port states will be stored.
+ *
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to read more ports than available.
+ * @retval NRF_SUCCESS If operation was successful.
+ */
+ret_code_t sx1509b_ports_read(uint8_t start_port, uint32_t length, uint8_t * p_masks);
+
+/**
+ * @brief Function for reading latch state of multiple consecutive ports.
+ *
+ * @note Due to specifics of TWI expander, latch data must be updated first
+ * to get current value @ref sx1509b_pin_latch_update
+ *
+ * @param start_port Index of the first port to read.
+ * @param length Number of ports to read.
+ * @param p_masks Pointer to output array where latch states will be stored.
+ *
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to read more ports than available.
+ * @retval NRF_SUCCESS If operation was successful.
+ */
+ret_code_t sx1509b_latches_read(uint8_t start_port, uint32_t length, uint8_t * p_masks);
+
+/**
+ * @brief Function for reading latch state of single pin.
+ *
+ * @note Due to specifics of TWI expander, latch data must be updated first
+ * to get current value @ref sx1509b_pin_latch_update
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval 0 Returned if latch is not set
+ * @retval 1 Returned if latch is set.
+ * @retval other Return from @ref sx1509b_pin_cfg_reg_get
+ */
+__STATIC_INLINE uint32_t sx1509b_pin_latch_get(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing latch state of a single pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_latch_clear(uint32_t pin_number);
+
+/**
+ * ===============================================================================================
+ * @brief Led driver functions.
+ */
+
+/**
+ * @brief Function enabling led driver.
+ *
+ * @param instance_num Number of expander instance.
+ * @param clock_internal Sets clock source.
+ * @arg true External clock source
+ * @arg false Internal 2Mhz clock
+ * @param frequency Frequency divider.
+ * @arg 0 Led driver functionality is disabled for all IOs.
+ * @arg Else Divider value, refer to expander documentation.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if given instance isn't present.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_driver_enable(uint8_t instance_num, bool clock_internal, uint8_t frequency);
+
+/**
+ * @brief Function for setting led driver mode.
+ *
+ * @param port_num Port for which mode will be set.
+ * @param mode Led driver mode.
+ * @arg true Logarithmic mode
+ * @arg false Linear mode
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if given port isn't present.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_mode(uint8_t port_num, bool mode);
+
+/**
+ * @brief Function for setting led driver pin times.
+ *
+ * @param pin_number Pin which settings will be changed.
+ * @param on_time On time of pin. Refer to expander documentation.
+ * @param on_intensity Intensity during on time. Between 0 and 255.
+ * @param off_time Off time of pin. Refer to expander documentation.
+ * @param off_intensity Intensity during off time. Between 0 and 7.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_time(uint32_t pin_number,
+ uint8_t on_time,
+ uint8_t on_intensity,
+ uint8_t off_time,
+ uint8_t off_intensity);
+
+/**
+ * @brief Function for setting led driver pin fade characteristics.
+ *
+ * @param pin_number Pin which settings will be changed.
+ * @param fade_in Fade in time of pin. Refer to expander documentation.
+ * @param fade_out Fade out time of pin. Refer to expander documentation.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if given pin has no fade capability,
+ * or there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_fade(uint32_t pin_number, uint8_t fade_in, uint8_t fade_out);
+
+/**
+ * @brief Function for enabling led driver on selected pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_enable(uint32_t pin_number);
+
+/**
+ * @brief Function for disabling led driver on selected pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_disable(uint32_t pin_number);
+
+/**
+ * @brief Function for getting led driver time on register of selected pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval Time on led driver register of selected pin
+ */
+uint8_t sx1509b_led_driver_get_reg(uint32_t pin_number);
+
+/**
+ * ===============================================================================================
+ * @brief Key Engine functions.
+ */
+
+/**
+ * @brief Function enabling key engine.
+ *
+ * @param instance_num Number of expander.
+ * @param rows Number of keyboard rows.
+ * @arg < 2 Disable key engine.
+ * @arg >= 2 Number of rows (max 8).
+ * @param columns Number of columns (max 8).
+ * @param sleep_time Time of inactivity before key engine enters sleep mode.
+ * @param scan_time Scan time per column. Must be bigger than debounce time.
+ * @param debounce_time Input debounce time.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_key_engine_enable(uint8_t instance_num,
+ uint8_t rows,
+ uint8_t columns,
+ sx1509b_key_sleep_t sleep_time,
+ sx1509b_key_scan_t scan_time,
+ sx1509b_debounce_t debounce_time);
+
+/**
+ * @brief Function scheduling key data update.
+ *
+ * @param instance_num Number of expander to update.
+ * @param user_cb Function called after key data update.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_key_data_update(uint8_t instance_num, nrf_twi_sensor_reg_cb_t user_cb);
+
+/**
+ * @brief Function returning pressed key column.
+ *
+ * @param instance_num Number of expander.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval 0xFF If no key was pressed.
+ * @retval 0 - 7 Column number.
+ */
+uint8_t sx1509b_key_column_get(uint8_t instance_num);
+
+/**
+ * @brief Function returning pressed key row.
+ *
+ * @param instance_num Number of expander.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval 0xFF If no key was pressed.
+ * @retval 0 - 7 Row number.
+ */
+uint8_t sx1509b_key_row_get(uint8_t instance_num);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ * ===============================================================================================
+ * @brief General expander inline utility functions.
+ */
+
+__STATIC_INLINE ret_code_t sx1509b_pin_long_slew(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_LONG_SLEW_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_low_drive(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_LOW_DRIVE_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_open_drain(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_OPEN_DRAIN_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_polarity(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_POLARITY_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_debounce(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DEBOUNCE_EN_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_level_shifter(uint32_t pin_number, sx1509b_level_shift_t set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_LEVEL_SHIFTER_1, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_long_slew(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_LONG_SLEW_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_low_drive(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_LOW_DRIVE_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_open_drain(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_OPEN_DRAIN_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_polarity(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_POLARITY_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_debounce(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DEBOUNCE_EN_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_pull_up(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_PULL_UP_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_pull_down(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, port_num, out_mask, flag);
+}
+
+/**
+ * ===============================================================================================
+ * @brief Inline functions compatible with nrf_gpio
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_output(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DIR_B, pin_number, SX1509B_PIN_DIR_OUTPUT);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_watcher(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_input(pin_number, SX1509B_PIN_NOPULL);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_input_disconnect(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_INPUT_DISABLE_B, pin_number, 1);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_set(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, SX1509B_PIN_SET);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_clear(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, SX1509B_PIN_CLR);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_toggle(uint32_t pin_number)
+{
+ uint8_t val = sx1509b_pin_cfg_reg_get(SX1509B_REG_DATA_B, pin_number);
+ val = !val;
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, val);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_write(uint32_t pin_number, sx1509b_pin_set_t value)
+{
+ value = (value >= 1) ? 1 : 0;
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, value);
+}
+
+__STATIC_INLINE uint32_t sx1509b_pin_read(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_DATA_B, pin_number);
+}
+
+__STATIC_INLINE uint32_t sx1509b_pin_out_read(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_DATA_B, pin_number);
+}
+
+__STATIC_INLINE sx1509b_pin_sense_t sx1509b_pin_sense_get(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_SENSE_H_B, pin_number);
+}
+
+__STATIC_INLINE uint8_t sx1509b_pin_port_decode(uint32_t pin_number)
+{
+ return pin_number / SX1509B_INNER_NEXT_BANK;
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_dir_output_set(uint8_t port_num, uint8_t out_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DIR_B, port_num, out_mask, SX1509B_PORT_CLEAR);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_dir_input_set(uint8_t port_num, uint8_t in_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DIR_B, port_num, in_mask, SX1509B_PORT_SET);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_dir_write(uint8_t port_num, uint8_t dir_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DIR_B, port_num, ~dir_mask, SX1509B_PORT_WRITE);
+}
+
+__STATIC_INLINE uint8_t sx1509b_port_dir_read(uint8_t port_num)
+{
+ return ~sx1509b_port_cfg_reg_get(SX1509B_REG_DIR_B, port_num);
+}
+
+__STATIC_INLINE uint8_t sx1509b_port_in_read(uint8_t port_num)
+{
+ return sx1509b_port_cfg_reg_get(SX1509B_REG_DATA_B, port_num);
+}
+
+__STATIC_INLINE uint8_t sx1509b_port_out_read(uint8_t port_num)
+{
+ return sx1509b_port_cfg_reg_get(SX1509B_REG_DATA_B, port_num);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_out_write(uint8_t port_num, uint8_t value)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DATA_B, port_num, value, SX1509B_PORT_WRITE);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_out_set(uint8_t port_num, uint8_t set_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DATA_B, port_num, set_mask, SX1509B_PORT_SET);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_out_clear(uint8_t port_num, uint8_t clr_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DATA_B, port_num, clr_mask, SX1509B_PORT_CLEAR);
+}
+
+__STATIC_INLINE uint32_t sx1509b_pin_latch_get(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_INT_SRC_B, pin_number);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SX1509B_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h
new file mode 100644
index 0000000..a5f2051
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h
@@ -0,0 +1,232 @@
+/**
+ * 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 SX1509B_INTERNAL_H
+#define SX1509B_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Device and IO banks registers.
+ */
+typedef enum
+{
+ SX1509B_REG_INPUT_DISABLE_B,
+ SX1509B_REG_INPUT_DISABLE_A,
+ SX1509B_REG_LONG_SLEW_B,
+ SX1509B_REG_LONG_SLEW_A,
+ SX1509B_REG_LOW_DRIVE_B,
+ SX1509B_REG_LOW_DRIVE_A,
+ SX1509B_REG_PULL_UP_B,
+ SX1509B_REG_PULL_UP_A,
+ SX1509B_REG_PULL_DOWN_B,
+ SX1509B_REG_PULL_DOWN_A,
+ SX1509B_REG_OPEN_DRAIN_B,
+ SX1509B_REG_OPEN_DRAIN_A,
+ SX1509B_REG_POLARITY_B,
+ SX1509B_REG_POLARITY_A,
+ SX1509B_REG_DIR_B,
+ SX1509B_REG_DIR_A,
+ SX1509B_REG_DATA_B,
+ SX1509B_REG_DATA_A,
+ SX1509B_REG_INT_MASK_B,
+ SX1509B_REG_INT_MASK_A,
+ SX1509B_REG_SENSE_H_B,
+ SX1509B_REG_SENSE_L_B,
+ SX1509B_REG_SENSE_H_A,
+ SX1509B_REG_SENSE_L_A,
+ SX1509B_REG_INT_SRC_B,
+ SX1509B_REG_INT_SRC_A,
+ SX1509B_REG_EVENT_STATUS_B,
+ SX1509B_REG_EVENT_STATUS_A,
+ SX1509B_REG_LEVEL_SHIFTER_1,
+ SX1509B_REG_LEVEL_SHIFTER_2,
+ SX1509B_REG_CLOCK,
+ SX1509B_REG_MISC,
+ SX1509B_REG_LED_DRV_ENABLE_B,
+ SX1509B_REG_LED_DRV_ENABLE_A,
+ SX1509B_REG_DEBOUNCE_CONFIG,
+ SX1509B_REG_DEBOUNCE_EN_B,
+ SX1509B_REG_DEBOUNCE_EN_A,
+ SX1509B_REG_KEY_CONFIG_1,
+ SX1509B_REG_KEY_CONFIG_2,
+ SX1509B_REG_KEY_DATA_1,
+ SX1509B_REG_KEY_DATA_2,
+ SX1509B_REG_COUNT
+} sx1509b_registers_t;
+
+#define SX1509B_INNER_PIN_COUNT 16
+#define SX1509B_INNER_NEXT_BANK 8
+
+#define SX1509B_INNER_PORT_COUNT 2
+#define SX1509B_INNER_SENSE_REG_NUM 4
+#define SX1509B_INNER_RESET_BYTE1 0x12
+#define SX1509B_INNER_RESET_BYTE2 0x34
+/**
+ * @brief LED Driver registers.
+ */
+#define SX1509B_REG_LED_BANK_A_START 0x29
+#define SX1509B_REG_LED_FADE_A_START 0x35
+#define SX1509B_REG_LED_BANK_B_START 0x49
+#define SX1509B_REG_LED_FADE_B_START 0x55
+
+#define SX1509B_LED_DRIVER_TIME_REG_LEN 3
+#define SX1509B_LED_DRIVER_FADE_REG_LEN 5
+#define SX1509B_LED_DRIVER_TIME_REG_NUM ((SX1509B_REG_LED_FADE_A_START \
+ - SX1509B_REG_LED_BANK_A_START) \
+ / SX1509B_LED_DRIVER_TIME_REG_LEN)
+
+#define SX1509B_LED_DRIVER_FADE_REG_NUM ((SX1509B_REG_LED_BANK_B_START \
+ - SX1509B_REG_LED_FADE_A_START) \
+ / SX1509B_LED_DRIVER_FADE_REG_LEN)
+
+/**
+ * @brief Clock register bitmasks.
+ */
+
+// Bitmasks for osc src.
+#define SX1509B_OSC_SRC_POS 5
+#define SX1509B_OSC_SRC_MASK (3 << SX1509B_OSC_SRC_POS)
+
+// Bitmasks for oscio pin.
+#define SX1509B_OSCIO_PIN_POS 4
+#define SX1509B_OSCIO_PIN_MASK (1 << SX1509B_OSCIO_PIN_POS)
+
+// Bitmasks for oscout freq.
+#define SX1509B_OSCOUT_FREQ_POS 0
+#define SX1509B_OSCOUT_FREQ_MASK (0x0F << SX1509B_OSCOUT_FREQ_POS)
+
+
+/**
+ * @brief Miscellaneous register bitmasks.
+ */
+
+// Bitmasks for led mode b.
+#define SX1509B_LED_MODE_B_POS 7
+#define SX1509B_LED_MODE_B_MASK (1 << SX1509B_LED_MODE_B_POS)
+
+// Bitmasks for led freq.
+#define SX1509B_LED_FREQ_POS 4
+#define SX1509B_LED_FREQ_MASK (7 << SX1509B_LED_FREQ_POS)
+
+// Bitmasks for led mode a.
+#define SX1509B_LED_MODE_A_POS 3
+#define SX1509B_LED_MODE_A_MASK (1 << SX1509B_LED_MODE_A_POS)
+
+// Bitmasks for nreset pin.
+#define SX1509B_NRESET_PIN_POS 2
+#define SX1509B_NRESET_PIN_MASK (1 << SX1509B_NRESET_PIN_POS)
+
+// Bitmasks for auto incr.
+#define SX1509B_AUTO_INCR_POS 1
+#define SX1509B_AUTO_INCR_MASK (1 << SX1509B_AUTO_INCR_POS)
+
+// Bitmasks for auto clear nint.
+#define SX1509B_AUTO_CLEAR_NINT_POS 0
+#define SX1509B_AUTO_CLEAR_NINT_MASK (1 << SX1509B_AUTO_CLEAR_NINT_POS)
+
+
+/**
+ * @brief Key config 1 register bitmasks.
+ */
+
+// Bitmasks for sleep time.
+#define SX1509B_SLEEP_TIME_POS 4
+#define SX1509B_SLEEP_TIME_MASK (7 << SX1509B_SLEEP_TIME_POS)
+
+// Bitmasks for scan time.
+#define SX1509B_SCAN_TIME_POS 0
+#define SX1509B_SCAN_TIME_MASK (7 << SX1509B_SCAN_TIME_POS)
+
+
+/**
+ * @brief Key config 2 register bitmasks.
+ */
+
+// Bitmasks for row num.
+#define SX1509B_ROW_NUM_POS 3
+#define SX1509B_ROW_NUM_MASK (7 << SX1509B_ROW_NUM_POS)
+
+// Bitmasks for col num.
+#define SX1509B_COL_NUM_POS 0
+#define SX1509B_COL_NUM_MASK (7 << SX1509B_COL_NUM_POS)
+
+
+/**
+ * @brief Led driver off register bitmasks.
+ */
+
+// Bitmasks for OFF_TIME.
+#define SX1509B_OFF_TIME_POS 3
+#define SX1509B_OFF_TIME_MASK (0x1F << SX1509B_OFF_TIME_POS)
+
+// Bitmasks for off intensity.
+#define SX1509B_OFF_INTENSITY_POS 0
+#define SX1509B_OFF_INTENSITY_MASK (7 << SX1509B_OFF_INTENSITY_POS)
+
+
+/**
+ * @brief Miscellaneous registers.
+ */
+#define SX1509B_REG_HIGH_INPUT_B 0x69
+#define SX1509B_REG_HIGH_INPUT_A 0x6A
+#define SX1509B_REG_SW_RESET 0x7D
+#define SX1509B_REG_TEST_1 0x7E
+#define SX1509B_REG_TEST_2 0x7F
+
+/**
+ * @brief Structure containing expander instance.
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * p_sensor_data;
+ uint8_t sensor_addr;
+ uint8_t start_addr;
+ uint8_t registers[SX1509B_REG_COUNT];
+ uint8_t high_input[2];
+} sx1509b_instance_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SX1509B_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c
new file mode 100644
index 0000000..53294ad
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING 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 "twi_master.h"
+#include "synaptics_touchpad.h"
+
+/*lint ++flb "Enter library region" */
+
+#define PRODUCT_ID_BYTES 10U //!< Number of bytes to expect to be in product ID
+
+static uint8_t m_device_address; // !< Device address in bits [7:1]
+static const uint8_t expected_product_id[PRODUCT_ID_BYTES] = {'T', 'M', '1', '9', '4', '4', '-', '0', '0', '2'}; //!< Product ID expected to get from product ID query
+
+bool touchpad_init(uint8_t device_address)
+{
+ bool transfer_succeeded = true;
+
+ m_device_address = (uint8_t)(device_address << 1);
+
+ // Do a soft reset
+ uint8_t reset_command = 0x01;
+ transfer_succeeded &= touchpad_write_register(TOUCHPAD_RESET, reset_command);
+
+ // Page select 0
+ uint8_t page_to_select = 0x00;
+ transfer_succeeded &= touchpad_write_register(TOUCHPAD_PAGESELECT, page_to_select);
+
+ // Read and verify product ID
+ transfer_succeeded &= touchpad_product_id_verify();
+
+ return transfer_succeeded;
+}
+
+
+bool touchpad_product_id_verify(void)
+{
+ bool transfer_succeeded = true;
+ uint8_t product_id[PRODUCT_ID_BYTES];
+ transfer_succeeded &= touchpad_product_id_read(product_id, PRODUCT_ID_BYTES);
+
+ for (uint8_t i = 0; i < 10; i++)
+ {
+ if (product_id[i] != expected_product_id[i])
+ {
+ transfer_succeeded = false;
+ }
+ }
+
+ return transfer_succeeded;
+}
+
+bool touchpad_reset(void)
+{
+ uint8_t w2_data[2] = {TOUCHPAD_COMMAND, 0x01};
+
+ return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
+}
+
+bool touchpad_interrupt_status_read(uint8_t *interrupt_status)
+{
+ return touchpad_read_register(TOUCHPAD_INT_STATUS, interrupt_status);
+}
+
+bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode)
+{
+ return touchpad_write_register(TOUCHPAD_CONTROL, (uint8_t)mode);
+}
+
+bool touchpad_read_register(uint8_t register_address, uint8_t *value)
+{
+ bool transfer_succeeded = true;
+ transfer_succeeded &= twi_master_transfer(m_device_address, &register_address, 1, TWI_DONT_ISSUE_STOP);
+ if (transfer_succeeded)
+ {
+ transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, value, 1, TWI_ISSUE_STOP);
+ }
+ return transfer_succeeded;
+}
+
+bool touchpad_write_register(uint8_t register_address, const uint8_t value)
+{
+ uint8_t w2_data[2];
+
+ w2_data[0] = register_address;
+ w2_data[1] = value;
+ return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
+}
+
+bool touchpad_product_id_read(uint8_t * product_id, uint8_t product_id_bytes)
+{
+ uint8_t w2_data[1];
+ bool transfer_succeeded = true;
+
+ w2_data[0] = TOUCHPAD_PRODUCT_ID;
+ transfer_succeeded &= twi_master_transfer(m_device_address, w2_data, 1, TWI_DONT_ISSUE_STOP);
+ if (transfer_succeeded)
+ {
+ transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, product_id, product_id_bytes, TWI_ISSUE_STOP);
+ }
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h
new file mode 100644
index 0000000..1996396
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2009 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef SYNAPTICS_TOUCHPAD_H
+#define SYNAPTICS_TOUCHPAD_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief Synaptics Touchpad driver
+*
+*
+* @defgroup nrf_drivers_synaptics_touchpad Synaptics Touchpad driver
+* @{
+* @ingroup ext_drivers
+* @brief Synaptics Touchpad driver.
+*/
+
+/**
+ Touchpad register addresses.
+*/
+#define TOUCHPAD_INT_STATUS 0x14 //!< Interrupt status register
+#define TOUCHPAD_BUTTON_STATUS 0x41 //!< Button status register
+#define TOUCHPAD_FINGER0_REL 0x30 //!< First register in finger delta block
+#define TOUCHPAD_GESTURE_FLAGS 0x3A //!< Gesture flags 0
+#define TOUCHPAD_SCROLL 0x3F //!< Scroll zone X / horizontal multifinger scroll
+#define TOUCHPAD_CONTROL 0x42 //!< Device control register
+#define TOUCHPAD_COMMAND 0x8F //!< Device command register
+
+#define TOUCHPAD_RESET 0x54 //!< Address of reset
+#define TOUCHPAD_PAGESELECT 0xFF //!< Address of page select (can be found in every page at the same address)
+#define TOUCHPAD_PRODUCT_ID 0xA2 //!< Address of product ID string
+
+/**
+ Operational states
+*/
+typedef enum
+{
+ SleepmodeNormal = 0x00, //!< Normal operation
+ SleepmodeSensorSleep = 0x01 //!< Low power operation
+} TouchpadSleepMode_t;
+
+/**
+ @brief Function for Touchpad initialization.
+ @param device_address TWI address of the device in bits [6:0]
+ @retval true Touchpad was successfully identified and initialized
+ @retval false Unexpected product ID or communication failure
+*/
+bool touchpad_init(uint8_t device_address);
+
+/**
+ @brief Function for attempting to soft-reset the device.
+ @retval true Reset succeeded
+ @retval false Reset failed
+*/
+bool touchpad_reset(void);
+
+/**
+ @brief Function for reading the interrupt status register of the device. This clears all interrupts.
+ @param interrupt_status Address to store interrupt status to.
+ @retval true Register contents read successfully to interrupt_status
+ @retval false Reading failed
+*/
+bool touchpad_interrupt_status_read(uint8_t *interrupt_status);
+
+/**
+ @brief Function for sleep mode configuration.
+ @note In low power mode the touchpad do not generate interrupts from touch sensing.
+ @param[in] mode Operational mode
+ @retval true Sleep mode set successfully
+ @retval false Sleep mode setting failed
+*/
+bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode);
+
+/**
+ @brief Function for reading a touchpad register contents over TWI.
+ @param[in] register_address Register address
+ @param[out] value Pointer to a data buffer where read data will be stored
+ @retval true Register read succeeded
+ @retval false Register read failed
+*/
+bool touchpad_read_register(uint8_t register_address, uint8_t *value);
+
+/**
+ @brief Function for writing a touchpad register contents over TWI.
+ @param[in] register_address Register address
+ @param[in] value Value to write to register
+ @retval true Register write succeeded
+ @retval false Register write failed
+*/
+bool touchpad_write_register(uint8_t register_address, uint8_t value);
+
+/**
+ @brief Function for writing touchpad register contents over TWI.
+ Writes one or more consecutive registers.
+ @param[out] product_id Pointer to a address to store product ID. Memory must be allocated for product_id_bytes number of bytes.
+ @param[in] product_id_bytes Number of bytes to read
+ @retval true Product ID read succeeded
+ @retval false Product ID read failed
+*/
+bool touchpad_product_id_read(uint8_t *product_id, uint8_t product_id_bytes);
+
+/**
+ @brief Function for reading and verifying touchpad's product ID.
+ @retval true Product ID is what was expected
+ @retval false Product ID was not what was expected
+*/
+bool touchpad_product_id_verify(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TOUCHPAD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c
new file mode 100644
index 0000000..05095d7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c
@@ -0,0 +1,124 @@
+/**
+ * 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 "uda1380.h"
+#include <string.h>
+
+ret_code_t uda1380_init(uda1380_iface_t const * p_iface,
+ uda1380_reg_t const * p_reg_config,
+ size_t reg_size)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ ret = nrf_drv_twi_init(&p_iface->twi, &p_iface->twi_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_drv_twi_enable(&p_iface->twi);
+
+ /*Probe device*/
+ uint8_t rx[] = {0};
+ ret = nrf_drv_twi_rx(&p_iface->twi, p_iface->twi_addr, rx, sizeof(rx));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ for (size_t i = 0; i < reg_size; ++i)
+ {
+ uint8_t p_dat[sizeof(uda1380_reg_t)];
+ memcpy(p_dat, &p_reg_config[i], sizeof(uda1380_reg_t));
+ ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+ret_code_t uda1380_enable(uda1380_iface_t const * p_iface)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ static const uda1380_reg_t enable[] = {
+ UDA1380_REG_INIT(UDA1380_REG_PWR, 0xA500),
+ UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0332),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(enable); ++i)
+ {
+ uint8_t p_dat[sizeof(uda1380_reg_t)];
+ memcpy(p_dat, &enable[i], sizeof(uda1380_reg_t));
+ ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+ret_code_t uda1380_disable(uda1380_iface_t const * p_iface)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ static const uda1380_reg_t disable[] = {
+ UDA1380_REG_INIT(UDA1380_REG_PWR, 0x0000),
+ UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0000),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(disable); ++i)
+ {
+ const uint8_t * p_dat = (const uint8_t *)&disable[i];
+ ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h
new file mode 100644
index 0000000..321ff31
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.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 UDA1380_H__
+#define UDA1380_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "nrf_drv_twi.h"
+
+
+#define UDA1380_REG_CLK 0x00
+#define UDA1380_REG_I2S 0x01
+#define UDA1380_REG_PWR 0x02
+#define UDA1380_REG_AMIX 0x03
+#define UDA1380_REG_HPA 0x04
+
+#define UDA1380_REG_VOL 0x10
+#define UDA1380_REG_MIX_VOL 0x11
+#define UDA1380_REG_PPROC 0x12
+#define UDA1380_REG_DEEMP 0x13
+#define UDA1380_REG_MIXER 0x14
+
+#define UDA1380_REG_RESET 0x7F
+
+
+/**
+ * @brief Default UDA1380 TWI configuration
+ *
+ * @param scl_pin SCL pin number
+ * @param sda_pin SDA pin number
+ */
+#define UDA1380_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \
+ .scl = scl_pin, \
+ .sda = sda_pin, \
+ .frequency = NRF_DRV_TWI_FREQ_100K, \
+ .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \
+ .clear_bus_init = false, \
+ .hold_bus_uninit = false \
+}
+
+/**
+ * @brief UDA1380 register descriptor
+ * */
+typedef struct {
+ uint8_t addr; //!< Internal register address
+ uint8_t val[2]; //!< Internal register value
+} uda1380_reg_t;
+
+#define UDA1380_REG_INIT(address, value) { \
+ .addr = address, \
+ .val = {(value) / 256, (value) & 0xFF}, \
+}
+
+/**
+ * @brief UDA1380 TWI bus address*/
+#define UDA1380_TWI_ADDRESS (0x18)
+
+/**
+ * @brief UDA1380 interface
+ * */
+typedef struct {
+ nrf_drv_twi_t twi; //!< TWI instance
+ nrf_drv_twi_config_t twi_cfg; //!< TWI configuration
+ uint8_t twi_addr; //!< UDA1380 TWI address
+} uda1380_iface_t;
+
+
+/**
+ * @brief Initializes UDA1380 codec IC
+ *
+ * @param p_iface Communication interface
+ * @param p_reg_config Configuration registers
+ * @param reg_size Number of configuration registers
+ *
+ * @return Standard error code
+ * */
+ret_code_t uda1380_init(uda1380_iface_t const * p_iface,
+ uda1380_reg_t const * p_reg_config,
+ size_t reg_size);
+
+/**
+ * @brief Enable UDA1380 codec
+ *
+ * @return Standard error code
+ * */
+ret_code_t uda1380_enable(uda1380_iface_t const * p_iface);
+
+
+/**
+ * @brief Disable UDA1380 codec
+ *
+ * @return Standard error code
+ * */
+ret_code_t uda1380_disable(uda1380_iface_t const * p_iface);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UDA1380_H__ */