diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:08:59 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:12:21 +0200 |
commit | 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a (patch) | |
tree | ab49cc16ed0b853452c5c2ed2d3042416d628986 /thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext | |
download | iot-sensors-master.tar.gz iot-sensors-master.tar.bz2 iot-sensors-master.tar.xz iot-sensors-master.zip |
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext')
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, ®ister_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, ®ister_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__ */ |