初始版本
This commit is contained in:
358
components/drivers_ext/adns2080/adns2080.c
Normal file
358
components/drivers_ext/adns2080/adns2080.c
Normal file
@@ -0,0 +1,358 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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" */
|
||||
317
components/drivers_ext/adns2080/adns2080.h
Normal file
317
components/drivers_ext/adns2080/adns2080.h
Normal file
@@ -0,0 +1,317 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
203
components/drivers_ext/bh1745/bh1745.c
Normal file
203
components/drivers_ext/bh1745/bh1745.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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);
|
||||
}
|
||||
359
components/drivers_ext/bh1745/bh1745.h
Normal file
359
components/drivers_ext/bh1745/bh1745.h
Normal file
@@ -0,0 +1,359 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
180
components/drivers_ext/bh1745/bh1745_internal.h
Normal file
180
components/drivers_ext/bh1745/bh1745_internal.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
225
components/drivers_ext/ccs811/ccs811.c
Normal file
225
components/drivers_ext/ccs811/ccs811.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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);
|
||||
}
|
||||
|
||||
297
components/drivers_ext/ccs811/ccs811.h
Normal file
297
components/drivers_ext/ccs811/ccs811.h
Normal file
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
259
components/drivers_ext/ccs811/ccs811_internal.h
Normal file
259
components/drivers_ext/ccs811/ccs811_internal.h
Normal file
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
474
components/drivers_ext/cherry8x16/cherry8x16.c
Normal file
474
components/drivers_ext/cherry8x16/cherry8x16.c
Normal file
@@ -0,0 +1,474 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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);
|
||||
}
|
||||
}
|
||||
119
components/drivers_ext/cherry8x16/cherry8x16.h
Normal file
119
components/drivers_ext/cherry8x16/cherry8x16.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
154
components/drivers_ext/ds1624/ds1624.c
Normal file
154
components/drivers_ext/ds1624/ds1624.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Copyright (c) 2012 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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" */
|
||||
113
components/drivers_ext/ds1624/ds1624.h
Normal file
113
components/drivers_ext/ds1624/ds1624.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
255
components/drivers_ext/hts221/hts221.c
Normal file
255
components/drivers_ext/hts221/hts221.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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;
|
||||
}
|
||||
|
||||
|
||||
309
components/drivers_ext/hts221/hts221.h
Normal file
309
components/drivers_ext/hts221/hts221.h
Normal file
@@ -0,0 +1,309 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
235
components/drivers_ext/hts221/hts221_internal.h
Normal file
235
components/drivers_ext/hts221/hts221_internal.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
401
components/drivers_ext/ili9341/ili9341.c
Normal file
401
components/drivers_ext/ili9341/ili9341.c
Normal file
@@ -0,0 +1,401 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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)
|
||||
173
components/drivers_ext/lis2dh12/lis2dh12.c
Normal file
173
components/drivers_ext/lis2dh12/lis2dh12.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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);
|
||||
}
|
||||
491
components/drivers_ext/lis2dh12/lis2dh12.h
Normal file
491
components/drivers_ext/lis2dh12/lis2dh12.h
Normal file
@@ -0,0 +1,491 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
823
components/drivers_ext/lis2dh12/lis2dh12_internal.h
Normal file
823
components/drivers_ext/lis2dh12/lis2dh12_internal.h
Normal file
@@ -0,0 +1,823 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
320
components/drivers_ext/lps22hb/lps22hb.c
Normal file
320
components/drivers_ext/lps22hb/lps22hb.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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;
|
||||
}
|
||||
512
components/drivers_ext/lps22hb/lps22hb.h
Normal file
512
components/drivers_ext/lps22hb/lps22hb.h
Normal file
@@ -0,0 +1,512 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
365
components/drivers_ext/lps22hb/lps22hb_internal.h
Normal file
365
components/drivers_ext/lps22hb/lps22hb_internal.h
Normal file
@@ -0,0 +1,365 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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_POS, \
|
||||
(_low << 1) + _high);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LPS22HB_INTERNAL_H
|
||||
71
components/drivers_ext/max9850/max9850.c
Normal file
71
components/drivers_ext/max9850/max9850.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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);
|
||||
}
|
||||
130
components/drivers_ext/max9850/max9850.h
Normal file
130
components/drivers_ext/max9850/max9850.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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__ */
|
||||
156
components/drivers_ext/mcp4725/mcp4725.c
Normal file
156
components/drivers_ext/mcp4725/mcp4725.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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" */
|
||||
107
components/drivers_ext/mcp4725/mcp4725.h
Normal file
107
components/drivers_ext/mcp4725/mcp4725.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
108
components/drivers_ext/mpu6050/mpu6050.c
Normal file
108
components/drivers_ext/mpu6050/mpu6050.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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" */
|
||||
110
components/drivers_ext/mpu6050/mpu6050.h
Normal file
110
components/drivers_ext/mpu6050/mpu6050.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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 */
|
||||
559
components/drivers_ext/nrf21540/nrf21540.c
Normal file
559
components/drivers_ext/nrf21540/nrf21540.c
Normal file
@@ -0,0 +1,559 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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 "nrf21540.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "nrf21540_defs.h"
|
||||
#include "nrf21540_macro.h"
|
||||
#include "nrf_radio.h"
|
||||
#include "nrf_ppi.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "nrf_timer.h"
|
||||
#include "boards.h"
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#include "nrf_egu.h"
|
||||
#endif
|
||||
|
||||
#define NRF21540_BUSY_CHECK(mode) \
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING) \
|
||||
{ \
|
||||
while(is_driver_busy()) \
|
||||
{ \
|
||||
\
|
||||
} \
|
||||
} \
|
||||
else if (is_driver_busy()) \
|
||||
{ \
|
||||
return NRF_ERROR_BUSY; \
|
||||
}
|
||||
|
||||
#define NRF21540_ERROR_CHECK(invalid_state_condition) \
|
||||
if (device_state_get() == NRF21540_STATE_ERROR) \
|
||||
{ \
|
||||
m_nrf21540_data.busy = false; \
|
||||
return NRF_ERROR_INTERNAL; \
|
||||
} \
|
||||
if (invalid_state_condition) \
|
||||
{ \
|
||||
m_nrf21540_data.busy = false; \
|
||||
return NRF_ERROR_INVALID_STATE; \
|
||||
}
|
||||
|
||||
/**@brief nRF21540 chip state.
|
||||
*
|
||||
* @details driver state variable possible values.
|
||||
*/
|
||||
typedef enum {
|
||||
NRF21540_STATE_OFF, ///< Chip inactive, line PDN is low, SPI communication impossible.
|
||||
NRF21540_STATE_READY, ///< SPI is active, but nether transmit nor receive can be performed.
|
||||
NRF21540_STATE_TX, ///< Transmit state - chip can perform transmiting data.
|
||||
NRF21540_STATE_RX, ///< Receive state - chip can receive data.
|
||||
NRF21540_STATE_ERROR, ///< Invalid state - requires reinit.
|
||||
} nrf21540_state_t;
|
||||
|
||||
/**@brief nRF21540 static data. */
|
||||
static struct
|
||||
{
|
||||
volatile nrf21540_state_t cur_state; ///< driver state variable.
|
||||
volatile nrf21540_trx_t cur_direction; ///< currently serviced radio communication direction.
|
||||
volatile bool busy; ///< driver is busy at the moment (during changing state phase).
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
volatile uint32_t shorts;
|
||||
#endif
|
||||
} m_nrf21540_data;
|
||||
|
||||
/**@brief Function checks if nRF21540 driver is busy now.
|
||||
*
|
||||
* @details Based on driver busy variable.
|
||||
*
|
||||
* @return true if nRF21540 driver is busy.
|
||||
*/
|
||||
static inline bool is_driver_busy(void)
|
||||
{
|
||||
return m_nrf21540_data.busy;
|
||||
}
|
||||
|
||||
/**@brief Function checks if nRF21540 is powered down.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return true if nRF21540 is in power down state.
|
||||
*/
|
||||
static inline bool is_device_off(void)
|
||||
{
|
||||
return m_nrf21540_data.cur_state == NRF21540_STATE_OFF;
|
||||
}
|
||||
|
||||
/**@brief Function checks if nRF21540 is powered up state.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return true if nRF21540 is in power up state.
|
||||
*/
|
||||
static inline bool is_device_on(void)
|
||||
{
|
||||
return m_nrf21540_data.cur_state != NRF21540_STATE_OFF;
|
||||
}
|
||||
|
||||
/**@brief Function checks if nRF21540 can transmit or receive data.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return true if nRF21540 is in TX or RX mode.
|
||||
*/
|
||||
static inline bool is_device_ready_for_transmission(void)
|
||||
{
|
||||
return (m_nrf21540_data.cur_state == NRF21540_STATE_TX ||
|
||||
m_nrf21540_data.cur_state == NRF21540_STATE_RX);
|
||||
}
|
||||
|
||||
/**@brief Function changes driver state.
|
||||
*
|
||||
* @details Changes driver state variable value.
|
||||
*
|
||||
* @param[in] new_state state that will be store.
|
||||
*/
|
||||
static inline void device_state_set(nrf21540_state_t new_state)
|
||||
{
|
||||
m_nrf21540_data.cur_state = new_state;
|
||||
}
|
||||
|
||||
/**@brief Function returns driver state variable value.
|
||||
*
|
||||
* @details Based on driver state variable.
|
||||
*
|
||||
* @return @ref nrf21540_state_t based state variable value.
|
||||
*/
|
||||
static inline nrf21540_state_t device_state_get(void)
|
||||
{
|
||||
return m_nrf21540_data.cur_state;
|
||||
}
|
||||
|
||||
/**@brief Function returns task related to transmission direction.
|
||||
*
|
||||
* @param[in] dir direction of radio transfer. See @nrf21540_trx_t.
|
||||
*
|
||||
* @return task corresponding to given transmission direction.
|
||||
*/
|
||||
static inline nrf_radio_task_t nrf21540_task_get(nrf21540_trx_t dir)
|
||||
{
|
||||
return dir == NRF21540_TX ? NRF_RADIO_TASK_TXEN : NRF_RADIO_TASK_RXEN;
|
||||
}
|
||||
|
||||
/**@brief Function clears and disbles all PPI connections used by nRF21540 driver.
|
||||
*
|
||||
* @details Changes driver state variable value.
|
||||
*/
|
||||
static void ppi_cleanup(void)
|
||||
{
|
||||
nrf_ppi_channel_disable(NRF21540_PDN_PPI_CHANNEL);
|
||||
nrf_ppi_channel_disable(NRF21540_USER_PPI_CHANNEL);
|
||||
nrf_ppi_channel_disable(NRF21540_TRX_PPI_CHANNEL);
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(NRF21540_PDN_PPI_CHANNEL, 0, 0, 0);
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(NRF21540_USER_PPI_CHANNEL, 0, 0, 0);
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(NRF21540_TRX_PPI_CHANNEL, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**@brief Function clears nRF21540 driver events. */
|
||||
static void events_clear()
|
||||
{
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT);
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_START_TO_PDN_UP_EVENT);
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_READY);
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_DISABLED);
|
||||
}
|
||||
|
||||
/**@brief Timer interrupt handler.
|
||||
*
|
||||
* @details checking time related events occurences and changing driver state if necessary.
|
||||
*/
|
||||
void NRF21540_TIMER_IRQ_HANDLER(void)
|
||||
{
|
||||
if (nrf_timer_event_check(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT))
|
||||
{
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT);
|
||||
if (is_device_off() && nrf_gpio_pin_read(NRF21540_PDN_PIN) == 1)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_READY);
|
||||
}
|
||||
else if (is_device_on() && nrf_gpio_pin_read(NRF21540_PDN_PIN) == 0)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_OFF);
|
||||
ppi_cleanup();
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
device_state_set(NRF21540_STATE_ERROR);
|
||||
ppi_cleanup();
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief nRF21540 interrupt handler.
|
||||
*
|
||||
* @details checking radio related events occurences and changing driver state if necessary.
|
||||
*/
|
||||
void NRF21540_RADIO_IRQ_HANDLER(void)
|
||||
{
|
||||
if (NRF21540_RADIO_EVENT_CHECK(NRF21540_RADIO_EVENT_READY))
|
||||
{
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_READY);
|
||||
nrf_ppi_channel_disable(NRF21540_USER_PPI_CHANNEL);
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
if (NRF21540_RADIO_SHORTS_ENABLE_CHECK(RADIO_SHORTS_READY_START_Msk))
|
||||
{
|
||||
nrf_radio_task_trigger(NRF_RADIO_TASK_START);
|
||||
}
|
||||
#endif
|
||||
if (device_state_get() == NRF21540_STATE_READY)
|
||||
{
|
||||
device_state_set(m_nrf21540_data.cur_direction == NRF21540_TX ?
|
||||
NRF21540_STATE_TX : NRF21540_STATE_RX);
|
||||
ppi_cleanup();
|
||||
NRF21540_RADIO_INT_DISABLE(NRF21540_RADIO_READY_Msk);
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
}
|
||||
if (NRF21540_RADIO_EVENT_CHECK(NRF21540_RADIO_EVENT_DISABLED))
|
||||
{
|
||||
NRF21540_RADIO_EVENT_CLEAR(NRF21540_RADIO_EVENT_DISABLED);
|
||||
nrf_ppi_channel_disable(NRF21540_USER_PPI_CHANNEL);
|
||||
nrf_timer_task_trigger(NRF21540_TIMER, NRF_TIMER_TASK_START);
|
||||
if (is_device_ready_for_transmission())
|
||||
{
|
||||
NRF21540_RADIO_INT_DISABLE(NRF21540_RADIO_DISABLED_Msk);
|
||||
device_state_set(NRF21540_STATE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief Function resets nRF21540 driver.
|
||||
*
|
||||
* @details sets driver state variable to NRF21540_STATE_OFF value,
|
||||
* cleans all used PPIs and events.
|
||||
*/
|
||||
static void driver_reset(void)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_OFF);
|
||||
ppi_cleanup();
|
||||
events_clear();
|
||||
NRF21540_RADIO_INT_DISABLE(NRF21540_RADIO_INTERRUPT_MASK);
|
||||
m_nrf21540_data.busy = false;
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function sets either TX or RX direction.
|
||||
*
|
||||
* @details Configuration of all necessarily peripherals to transmit or receive data,
|
||||
* dependenly on interface used (SPI, or GPIO). Procedure configures nRF21540 chip and
|
||||
* starts transmitting/receiving. Procedure will be started immediately if
|
||||
* @ref trigger_event is 0. Otherwise event which address is @ref trigger_event value
|
||||
* will start procedure.
|
||||
*
|
||||
* @param[in] dir RX or TX communication that will be performed.
|
||||
* @param[in] trigger_event address of event which will trigger the procedure.
|
||||
* @param[in] mode if NRF21540_EXEC_MODE_BLOCKING the function will wait for tx/rx
|
||||
* possibility.
|
||||
* @return NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
static ret_code_t trx_set(nrf21540_trx_t dir, uint32_t trigger_event,
|
||||
nrf21540_execution_mode_t mode)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && trigger_event != 0));
|
||||
NRF21540_BUSY_CHECK(mode);
|
||||
NRF21540_ERROR_CHECK((dir == NRF21540_TX && device_state_get() == NRF21540_STATE_TX) ||
|
||||
(dir == NRF21540_RX && device_state_get() == NRF21540_STATE_RX));
|
||||
uint32_t ramp_up_time = nrf_radio_modecnf0_ru_get() ? FAST_RAMP_UP_TIME : RAMP_UP_TIME;
|
||||
nrf_radio_task_t radio_task_to_start = nrf21540_task_get(dir);
|
||||
m_nrf21540_data.busy = true;
|
||||
events_clear();
|
||||
NRF21540_RADIO_INT_ENABLE(NRF21540_RADIO_READY_Msk);
|
||||
if (is_device_off())
|
||||
{
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_PDN_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_START_TO_PDN_UP_EVENT),
|
||||
nrf_gpiote_task_addr_get(NRF21540_PDN_GPIOTE_TASK_SET));
|
||||
nrf_ppi_channel_enable(NRF21540_PDN_PPI_CHANNEL);
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_CHANNEL,
|
||||
ramp_up_time - NRF21540_PA_PG_TRX_TIME_US);
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL,
|
||||
ramp_up_time - NRF21540_PA_PG_TRX_TIME_US - NRF21540_PD_PG_TIME_US);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
nrf21540_gpio_trx_enable(dir);
|
||||
#elif NRF21540_USE_SPI_MANAGEMENT
|
||||
nrf21540_spim_for_trx_configure(dir, NRF21540_ENABLE);
|
||||
#endif
|
||||
nrf_timer_shorts_enable(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK |
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK);
|
||||
NRF21540_RADIO_SHORTS_ENABLE(RADIO_SHORTS_READY_START_Msk);
|
||||
if (trigger_event == 0)
|
||||
{
|
||||
//start immediately.
|
||||
nrf_timer_task_trigger(NRF21540_TIMER, NRF_TIMER_TASK_START);
|
||||
nrf_radio_task_trigger(radio_task_to_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
//start when user event occurs.
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(
|
||||
NRF21540_USER_PPI_CHANNEL,
|
||||
trigger_event,
|
||||
(uint32_t) nrf_timer_task_address_get(NRF21540_TIMER, NRF_TIMER_TASK_START),
|
||||
(uint32_t) nrf_radio_task_address_get(radio_task_to_start));
|
||||
nrf_ppi_channel_enable(NRF21540_USER_PPI_CHANNEL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// at the moment we are not able to switch direction on the fly.
|
||||
// @todo switching between RXEN and TXEN.
|
||||
NRF21540_ERROR_CHECK(device_state_get() == NRF21540_STATE_RX);
|
||||
if (trigger_event == 0)
|
||||
{
|
||||
nrf_radio_task_trigger(radio_task_to_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start when user event occurs
|
||||
nrf_ppi_channel_endpoint_setup(
|
||||
NRF21540_USER_PPI_CHANNEL,
|
||||
trigger_event,
|
||||
(uint32_t) nrf_radio_task_address_get(radio_task_to_start));
|
||||
nrf_ppi_channel_enable(NRF21540_USER_PPI_CHANNEL);
|
||||
}
|
||||
}
|
||||
m_nrf21540_data.cur_direction = dir;
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
while (!is_device_ready_for_transmission());
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_init(void)
|
||||
{
|
||||
driver_reset();
|
||||
// GPIOTE for PDN pin configuration
|
||||
nrf_gpiote_task_configure(NRF21540_PDN_GPIOTE_CHANNEL_NO,
|
||||
NRF21540_PDN_PIN,
|
||||
(nrf_gpiote_polarity_t) GPIOTE_CONFIG_POLARITY_None,
|
||||
NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(NRF21540_PDN_GPIOTE_CHANNEL_NO);
|
||||
nrf21540_gpio_init();
|
||||
NVIC_SetPriority(NRF21540_TIMER_IRQn, NRF21540_INTERRUPT_PRIORITY);
|
||||
NVIC_EnableIRQ(NRF21540_TIMER_IRQn);
|
||||
nrf_timer_int_enable(NRF21540_TIMER, NRF21540_TIM_INTERRUPT_MASK);
|
||||
#if NRF21540_USE_SPI_MANAGEMENT
|
||||
ret_code_t ret = NRF_SUCCESS;
|
||||
ret = nrf21540_spi_init();
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
device_state_set(NRF21540_STATE_ERROR);
|
||||
return ret;
|
||||
}
|
||||
#endif //NRF21540_USE_SPI_MANAGEMENT
|
||||
#if NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL,
|
||||
nrf_radio_event_address_get(NRF_RADIO_EVENT_READY),
|
||||
(uint32_t)nrf_egu_task_address_get(NRF21540_EGU, NRF21540_RADIO_READY_EGU_TASK));
|
||||
nrf_ppi_channel_enable(NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL);
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL,
|
||||
nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED),
|
||||
(uint32_t)nrf_egu_task_address_get(NRF21540_EGU, NRF21540_RADIO_DISABLED_EGU_TASK));
|
||||
nrf_ppi_channel_enable(NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL);
|
||||
#endif
|
||||
NVIC_SetPriority(NRF21540_RADIO_IRQn, NRF21540_INTERRUPT_PRIORITY);
|
||||
NVIC_EnableIRQ(NRF21540_RADIO_IRQn);
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf21540_pdn_drive(bool state, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
NRF21540_BUSY_CHECK(mode);
|
||||
NRF21540_ERROR_CHECK((state == true && is_device_on()) ||
|
||||
(state == false && is_device_off()));
|
||||
nrf21540_state_t final_state;
|
||||
if (state)
|
||||
{
|
||||
final_state = NRF21540_STATE_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
final_state = NRF21540_STATE_OFF;
|
||||
}
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_CHANNEL,
|
||||
state ? NRF21540_PD_PG_TIME_US : 0);
|
||||
nrf_timer_shorts_enable(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK |
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK);
|
||||
nrf_timer_event_clear(NRF21540_TIMER, NRF21540_TIMER_CC_PD_PG_EVENT);
|
||||
nrf_gpiote_task_force(NRF21540_PDN_GPIOTE_CHANNEL_NO,
|
||||
!state ? NRF_GPIOTE_INITIAL_VALUE_LOW : NRF_GPIOTE_INITIAL_VALUE_HIGH);
|
||||
nrf_timer_task_trigger(NRF21540_TIMER, NRF_TIMER_TASK_START);
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
while (device_state_get() != final_state)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_tx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
NRF21540_ERROR_CHECK(device_state_get() == NRF21540_STATE_TX);
|
||||
return trx_set(NRF21540_TX, user_trigger_event, mode);
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_rx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
NRF21540_ERROR_CHECK(device_state_get() == NRF21540_STATE_RX);
|
||||
return trx_set(NRF21540_RX, user_trigger_event, mode);
|
||||
}
|
||||
|
||||
|
||||
bool nrf21540_is_error(void)
|
||||
{
|
||||
return device_state_get() == NRF21540_STATE_ERROR ? true : false;
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_ant_set(nrf21540_antenna_t antenna)
|
||||
{
|
||||
NRF21540_BUSY_CHECK(NRF21540_EXEC_MODE_NON_BLOCKING);
|
||||
return nrf21540_gpio_ant_set(antenna);
|
||||
}
|
||||
|
||||
|
||||
ret_code_t nrf21540_pwr_mode_set(nrf21540_pwr_mode_t mode)
|
||||
{
|
||||
NRF21540_BUSY_CHECK(NRF21540_EXEC_MODE_NON_BLOCKING);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
return nrf21540_gpio_pwr_mode_set(mode);
|
||||
#elif NRF21540_USE_SPI_MANAGEMENT
|
||||
return nrf21540_spi_pwr_mode_set(mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_power_down(uint32_t user_trigger_event, nrf21540_execution_mode_t mode)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && user_trigger_event != 0));
|
||||
NRF21540_ERROR_CHECK(is_device_off());
|
||||
NRF21540_BUSY_CHECK(mode);
|
||||
m_nrf21540_data.busy = true;
|
||||
events_clear();
|
||||
NRF21540_RADIO_INT_ENABLE(NRF21540_RADIO_DISABLED_Msk);
|
||||
if (device_state_get() == NRF21540_STATE_READY)
|
||||
{
|
||||
// when device is in ready state we jus driving PDN line down and switch off the radio.
|
||||
(void)nrf21540_pdn_drive(false, NRF21540_EXEC_MODE_NON_BLOCKING);
|
||||
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// When device is in tx/rx state we have to leave it and then drive PDN down.
|
||||
// Line PDN should be driven low after 5us from triggering TXEN/RXEN.
|
||||
uint32_t * trx_drv_task_address;
|
||||
nrf21540_trx_t cur_direction;
|
||||
if (device_state_get() == NRF21540_STATE_TX)
|
||||
{
|
||||
cur_direction = NRF21540_TX;
|
||||
}
|
||||
else if (device_state_get() == NRF21540_STATE_RX)
|
||||
{
|
||||
cur_direction = NRF21540_RX;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_PDN_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_TRX_PG_EVENT),
|
||||
nrf_gpiote_task_addr_get(NRF21540_PDN_GPIOTE_TASK_CLR));
|
||||
nrf_ppi_channel_enable(NRF21540_PDN_PPI_CHANNEL);
|
||||
nrf_timer_shorts_enable(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK |
|
||||
NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK);
|
||||
nrf_timer_cc_write(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_TRX_PG_CHANNEL,
|
||||
NRF21540_TRX_PG_TIME_US);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
trx_drv_task_address = (uint32_t*) nrf21540_gpio_trx_task_start_address_get(cur_direction,
|
||||
NRF21540_DISABLE);
|
||||
#elif NRF21540_USE_SPI_MANAGEMENT
|
||||
nrf21540_spim_for_trx_configure(cur_direction, NRF21540_DISABLE);
|
||||
trx_drv_task_address = (uint32_t*) nrf21540_spim_trx_task_start_address_get();
|
||||
#endif
|
||||
if (user_trigger_event == 0)
|
||||
{
|
||||
*trx_drv_task_address = 1;
|
||||
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// start when user event occurs.
|
||||
nrf_ppi_channel_and_fork_endpoint_setup(
|
||||
NRF21540_USER_PPI_CHANNEL,
|
||||
user_trigger_event,
|
||||
(uint32_t)nrf_radio_task_address_get(NRF_RADIO_TASK_DISABLE),
|
||||
(uint32_t) trx_drv_task_address);
|
||||
nrf_ppi_channel_enable(NRF21540_USER_PPI_CHANNEL);
|
||||
}
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
while (is_device_on());
|
||||
}
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
194
components/drivers_ext/nrf21540/nrf21540.h
Normal file
194
components/drivers_ext/nrf21540/nrf21540.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF21540_H_
|
||||
#define NRF21540_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "nrf21540_spi.h"
|
||||
#include "nrf21540_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @file
|
||||
* @brief nRF21540 front-end Bluetooth range extender.
|
||||
*
|
||||
*
|
||||
* @defgroup nrf21540 nRF21540 front-end Bluetooth range extender.
|
||||
* @{
|
||||
* @ingroup ext_drivers
|
||||
* @brief nRF21540 front-end Bluetooth range extender.
|
||||
*/
|
||||
|
||||
#if NRF21540_USE_SPI_MANAGEMENT
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
#error Only one management manner can be active
|
||||
#endif
|
||||
#elif !NRF21540_USE_GPIO_MANAGEMENT
|
||||
#error At least one management manner must be active
|
||||
#endif // NRF21540_USE_SPI_MANAGEMENT
|
||||
|
||||
/**@brief Initialization of modules needed by nRF21540:
|
||||
* - SPI
|
||||
* - GPIO
|
||||
* - GPIOTE
|
||||
* - PPI
|
||||
* - RADIO
|
||||
* - NVIC
|
||||
*
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_INTERNAL when driver is in error state,
|
||||
* or SPI initialization has failed. Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_init(void);
|
||||
|
||||
/**@brief Set nRF21540 to TX mode.
|
||||
*
|
||||
* @note Dependently on configuration GPIO or SPI interface will be used.
|
||||
*
|
||||
* @param[in] user_trigger_event event that triggers start of procedure - this event
|
||||
* will be connected to appropriate PPI channel.
|
||||
* @ref NRF21540_EXECUTE_NOW value causes start procedure
|
||||
* immediately.
|
||||
* @param[in] mode @ref NRF21540_EXEC_MODE_BLOCKING - function will wait for
|
||||
* finishing configuration including settling times required
|
||||
* by nRF21540 (waits till all procedure has finished).
|
||||
* @ref NRF21540_EXEC_MODE_NON_BLOCKING - function will start
|
||||
* procedure and set busy flag. User code can be executed
|
||||
* at this time and busy flag will be unset when done.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_tx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode);
|
||||
|
||||
/**@brief Set nRF21540 to TX mode.
|
||||
*
|
||||
* @note Dependently on configuration GPIO or SPI interface will be used
|
||||
* (NRF21540_USE_SPI_MANAGEMENT/NRF21540_USE_GPIO_MANAGEMENT).
|
||||
*
|
||||
* @param[in] user_trigger_event event that triggers start of procedure - this event
|
||||
* will be connected to appropriate PPI channel.
|
||||
* @ref NRF21540_EXECUTE_NOW value causes start procedure
|
||||
* immediately.
|
||||
* @param[in] mode @ref NRF21540_EXEC_MODE_BLOCKING - function will wait for
|
||||
* finishing configuration including settling times required
|
||||
* by nRF21540 (waits till all procedure has finished).
|
||||
* @ref NRF21540_EXEC_MODE_NON_BLOCKING - function will start
|
||||
* procedure and set busy flag. User code can be executed
|
||||
* at this time and busy flag will be unset when done.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_rx_set(uint32_t user_trigger_event, nrf21540_execution_mode_t mode);
|
||||
|
||||
/**@brief Function choses one of two physical antenna outputs.
|
||||
*
|
||||
* @param[in] antenna One of antenna outputs. See @ref nrf21540_antenna_t.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_ant_set(nrf21540_antenna_t antenna);
|
||||
|
||||
/**@brief Function choses one of two predefined power modes in nRF21540.
|
||||
*
|
||||
* @details Refer to nRF21540 Objective Product Specification, section: TX power control.
|
||||
*
|
||||
* @param[in] mode Power mode. See @ref nrf21540_pwr_mode_t.
|
||||
* @return NRF based error code.
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_pwr_mode_set(nrf21540_pwr_mode_t mode);
|
||||
|
||||
/**@brief nRF21540 power down.
|
||||
*
|
||||
* @details Disables chip functionality and enter power save mode.
|
||||
*
|
||||
* @note Dependently on configuration GPIO or SPI interface will be used.
|
||||
*
|
||||
* @param[in] user_trigger_event event that triggers start of procedure - this event
|
||||
* will be connected to appropriate PPI channel.
|
||||
* @ref NRF21540_EXECUTE_NOW value causes start procedure
|
||||
* immediately.
|
||||
* @param[in] mode @ref NRF21540_EXEC_MODE_BLOCKING - function will wait for
|
||||
* finishing configuration including settling times required
|
||||
* by nRF21540 (waits till all procedure has finished).
|
||||
* @ref NRF21540_EXEC_MODE_NON_BLOCKING - function will start
|
||||
* procedure and set busy flag. User code can be executed
|
||||
* at this time and busy flag will be unset when done.
|
||||
* @return NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required then.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_ERROR_BUSY when driver performs another operation at
|
||||
* the moment.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_power_down(uint32_t user_trigger_event, nrf21540_execution_mode_t mode);
|
||||
|
||||
/**@brief Checks if nRF21540 driver is in error state.
|
||||
*
|
||||
* @return true if driver is in error state and should be reinitialized.
|
||||
*/
|
||||
bool nrf21540_is_error(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_H_
|
||||
183
components/drivers_ext/nrf21540/nrf21540_defs.h
Normal file
183
components/drivers_ext/nrf21540/nrf21540_defs.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF21540_DEFS_H_
|
||||
#define NRF21540_DEFS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macros creating instance channels number dependent parameters.
|
||||
*/
|
||||
#define NRF21540_TIMER CONCAT_2(NRF_TIMER, NRF21540_TIMER_NO)
|
||||
#define NRF21540_TIMER_IRQ_HANDLER CONCAT_3(TIMER, NRF21540_TIMER_NO, _IRQHandler)
|
||||
#define NRF21540_TIMER_IRQn CONCAT_3(TIMER, NRF21540_TIMER_NO, _IRQn)
|
||||
#define NRF21540_TIM_INTERRUPT_MASK CONCAT_3(TIMER_INTENSET_COMPARE, \
|
||||
NRF21540_TIMER_CC_PD_PG_CHANNEL_NO, _Msk)
|
||||
|
||||
#if NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL_NO == NRF21540_TIMER_CC_PD_PG_CHANNEL_NO
|
||||
#error These CC channels must be different
|
||||
#endif
|
||||
|
||||
#if (NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_USER_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_TRX_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_TRX_PPI_CHANNEL_NO == NRF21540_USER_PPI_CHANNEL_NO)
|
||||
#error These PPI channels must be different
|
||||
#endif
|
||||
|
||||
#define NRF21540_USER_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_USER_PPI_CHANNEL_NO)
|
||||
#define NRF21540_PDN_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_PDN_PPI_CHANNEL_NO)
|
||||
#define NRF21540_TRX_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_TRX_PPI_CHANNEL_NO)
|
||||
#define NRF21540_USER_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_USER_PPI_CHANNEL_NO)
|
||||
#define NRF21540_PDN_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_PDN_PPI_CHANNEL_NO)
|
||||
#define NRF21540_TRX_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_TRX_PPI_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_TIMER_CC_FINISHED_CHANNEL_STOP_MASK CONCAT_3(NRF_TIMER_SHORT_COMPARE, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO, _STOP_MASK)
|
||||
#define NRF21540_TIMER_CC_FINISHED_CHANNEL_CLEAR_MASK CONCAT_3(NRF_TIMER_SHORT_COMPARE, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO, _CLEAR_MASK)
|
||||
|
||||
#define NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL CONCAT_2(NRF_TIMER_CC_CHANNEL, NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_PD_PG_CHANNEL CONCAT_2(NRF_TIMER_CC_CHANNEL, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_TRX_PG_CHANNEL NRF21540_TIMER_CC_PD_PG_CHANNEL
|
||||
|
||||
#define NRF21540_TIMER_CC_START_TO_PDN_UP_EVENT CONCAT_2(NRF_TIMER_EVENT_COMPARE, NRF21540_TIMER_CC_START_TO_PDN_UP_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_PD_PG_EVENT CONCAT_2(NRF_TIMER_EVENT_COMPARE, NRF21540_TIMER_CC_PD_PG_CHANNEL_NO)
|
||||
#define NRF21540_TIMER_CC_TRX_PG_EVENT NRF21540_TIMER_CC_PD_PG_EVENT
|
||||
|
||||
#if (NRF21540_PDN_GPIOTE_CHANNEL_NO == NRF21540_PA_GPIOTE_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_GPIOTE_CHANNEL_NO == NRF21540_LNA_GPIOTE_CHANNEL_NO) || \
|
||||
(NRF21540_LNA_GPIOTE_CHANNEL_NO == NRF21540_PA_GPIOTE_CHANNEL_NO)
|
||||
#error These GPIOTE channels must be different
|
||||
#endif
|
||||
|
||||
#define NRF21540_PDN_GPIOTE_TASK_CLR CONCAT_2(NRF_GPIOTE_TASKS_CLR_, NRF21540_PDN_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_LNA_GPIOTE_TASK_CLR CONCAT_2(NRF_GPIOTE_TASKS_CLR_, NRF21540_LNA_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_PA_GPIOTE_TASK_CLR CONCAT_2(NRF_GPIOTE_TASKS_CLR_, NRF21540_PA_GPIOTE_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_PDN_GPIOTE_TASK_SET CONCAT_2(NRF_GPIOTE_TASKS_SET_, NRF21540_PDN_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_LNA_GPIOTE_TASK_SET CONCAT_2(NRF_GPIOTE_TASKS_SET_, NRF21540_LNA_GPIOTE_CHANNEL_NO)
|
||||
#define NRF21540_PA_GPIOTE_TASK_SET CONCAT_2(NRF_GPIOTE_TASKS_SET_, NRF21540_PA_GPIOTE_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_GPIO_TASK_SET(channel) CONCAT_2(NRF_GPIOTE_TASKS_SET_, channel)
|
||||
#define NRF21540_GPIO_TASK_CLR(channel) CONCAT_2(NRF_GPIOTE_TASKS_CLR_, channel)
|
||||
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_IRQ_HANDLER RADIO_IRQHandler
|
||||
#define NRF21540_RADIO_IRQn RADIO_IRQn
|
||||
#define NRF21540_RADIO_READY_Msk RADIO_INTENSET_READY_Msk
|
||||
#define NRF21540_RADIO_EVENT_READY NRF_RADIO_EVENT_READY
|
||||
#define NRF21540_RADIO_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk
|
||||
#define NRF21540_RADIO_EVENT_DISABLED NRF_RADIO_EVENT_DISABLED
|
||||
#else
|
||||
#if (NRF21540_USER_PPI_CHANNEL_NO == NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_TRX_PPI_CHANNEL_NO == NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_USER_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_PDN_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_TRX_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO) || \
|
||||
(NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO == NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO)
|
||||
#error These PPI channels must be different
|
||||
#endif
|
||||
|
||||
#if (NRF21540_RADIO_READY_EGU_CHANNEL_NO == NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
#error These EGU channels must be different
|
||||
#endif
|
||||
|
||||
#define NRF21540_EGU CONCAT_2(NRF_EGU, NRF21540_EGU_NO)
|
||||
#define SWIx_EGU CONCAT_3(SWI, NRF21540_EGU_NO, _EGU)
|
||||
#define NRF21540_RADIO_IRQ_HANDLER CONCAT_3(SWIx_EGU, NRF21540_EGU_NO, _IRQHandler)
|
||||
#define NRF21540_RADIO_IRQn CONCAT_3(SWIx_EGU, NRF21540_EGU_NO, _IRQn)
|
||||
#define NRF21540_RADIO_READY_Msk (1 << NRF21540_RADIO_READY_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_DISABLED_Msk (1 << NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_EVENT_READY CONCAT_2(NRF_EGU_EVENT_TRIGGERED, NRF21540_RADIO_READY_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_EVENT_DISABLED CONCAT_2(NRF_EGU_EVENT_TRIGGERED, NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_READY_EGU_TASK CONCAT_2(NRF_EGU_TASK_TRIGGER, NRF21540_RADIO_READY_EGU_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_DISABLED_EGU_TASK CONCAT_2(NRF_EGU_TASK_TRIGGER, NRF21540_RADIO_DISABLED_EGU_CHANNEL_NO)
|
||||
|
||||
#define NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_RADIO_READY_TO_EGU_PPI_CHANNEL_NO)
|
||||
#define NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL CONCAT_2(NRF_PPI_CHANNEL, NRF21540_RADIO_DISABLED_TO_EGU_PPI_CHANNEL_NO)
|
||||
#endif //!NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_INTERRUPT_MASK (NRF21540_RADIO_READY_Msk | NRF21540_RADIO_DISABLED_Msk)
|
||||
|
||||
/**@brief Time in microseconds when PA GPIO is activated before the radio is ready for
|
||||
* transmission.
|
||||
*/
|
||||
#define NRF21540_PA_PG_TRX_TIME_US 13
|
||||
|
||||
/**@brief Time in microseconds when LNA GPIO is activated before the radio is ready for
|
||||
* reception.
|
||||
*/
|
||||
#define NRF21540_LNA_PG_TRX_TIME_US 13
|
||||
|
||||
/**@brief The time between activating the PDN and asserting the RX_EN/TX_EN.
|
||||
*/
|
||||
#define NRF21540_PD_PG_TIME_US 18
|
||||
|
||||
/**@brief The time between deasserting the RX_EN/TX_EN and deactivating PDN.
|
||||
*/
|
||||
#define NRF21540_TRX_PG_TIME_US 5
|
||||
|
||||
/**@brief Timing definitions for radio peripheral on nRF uc.
|
||||
*/
|
||||
#define TX_FAST_RAMP_UP_TIME 40 ///< Radio fast ramp up time in us for tx
|
||||
#define RX_FAST_RAMP_UP_TIME 40 ///< Radio fast ramp up time in us for rx
|
||||
#define TX_RAMP_UP_TIME 130 ///< Radio normal ramp up time in us for tx
|
||||
#define RX_RAMP_UP_TIME 130 ///< Radio normal ramp up time in us for rx
|
||||
|
||||
#if (TX_RAMP_UP_TIME == RX_RAMP_UP_TIME && TX_FAST_RAMP_UP_TIME == RX_FAST_RAMP_UP_TIME)
|
||||
#define FAST_RAMP_UP_TIME TX_FAST_RAMP_UP_TIME
|
||||
#define RAMP_UP_TIME TX_RAMP_UP_TIME
|
||||
#else
|
||||
#error ramp up times for rx and tx direction are different. Driver needs rework
|
||||
#endif
|
||||
|
||||
#if (FAST_RAMP_UP_TIME < (NRF21540_PA_PG_TRX_TIME_US + NRF21540_PD_PG_TIME_US))
|
||||
#error fast ramp up time must be greater or equal than (TPD->PG + TPG->TRX)
|
||||
#endif
|
||||
|
||||
#if (FAST_RAMP_UP_TIME > RAMP_UP_TIME)
|
||||
#error fast ramp up time connot be greater than ramp up time
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_DEFS_H_
|
||||
126
components/drivers_ext/nrf21540/nrf21540_gpio.c
Normal file
126
components/drivers_ext/nrf21540/nrf21540_gpio.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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 "nrf21540_gpio.h"
|
||||
#include "nrf_assert.h"
|
||||
#include "boards.h"
|
||||
#include "nrf21540_defs.h"
|
||||
#include "nrf_gpiote.h"
|
||||
#include "nrf_ppi.h"
|
||||
#include "nrf_timer.h"
|
||||
|
||||
void nrf21540_gpio_init(void)
|
||||
{
|
||||
nrf_gpio_cfg_output(NRF21540_ANTSEL_PIN);
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
nrf_gpio_cfg_output(NRF21540_MODE_PIN);
|
||||
//GPIOTE for TXEN pin configuration
|
||||
nrf_gpiote_task_configure(NRF21540_PA_GPIOTE_CHANNEL_NO,
|
||||
NRF21540_TXEN_PIN,
|
||||
(nrf_gpiote_polarity_t) GPIOTE_CONFIG_POLARITY_None,
|
||||
NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(NRF21540_PA_GPIOTE_CHANNEL_NO);
|
||||
//GPIOTE for RXEN pin configuration
|
||||
nrf_gpiote_task_configure(NRF21540_LNA_GPIOTE_CHANNEL_NO,
|
||||
NRF21540_RXEN_PIN,
|
||||
(nrf_gpiote_polarity_t) GPIOTE_CONFIG_POLARITY_None,
|
||||
NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(NRF21540_LNA_GPIOTE_CHANNEL_NO);
|
||||
#endif /*NRF21540_USE_GPIO_MANAGEMENT*/
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_gpio_ant_set(nrf21540_antenna_t antenna)
|
||||
{
|
||||
if (antenna == NRF21540_ANT1)
|
||||
{
|
||||
nrf_gpio_pin_clear(NRF21540_ANTSEL_PIN);
|
||||
}
|
||||
else if (antenna == NRF21540_ANT2)
|
||||
{
|
||||
nrf_gpio_pin_set(NRF21540_ANTSEL_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
|
||||
uint32_t nrf21540_gpio_trx_task_start_address_get(nrf21540_trx_t dir,
|
||||
nrf21540_bool_state_t required_state)
|
||||
{
|
||||
uint8_t gpiote_rx_tx_channel =
|
||||
dir == NRF21540_TX ?
|
||||
NRF21540_PA_GPIOTE_CHANNEL_NO :
|
||||
NRF21540_LNA_GPIOTE_CHANNEL_NO;
|
||||
return required_state == NRF21540_ENABLE ?
|
||||
nrf_gpiote_task_addr_get(nrf_gpiote_set_task_get(gpiote_rx_tx_channel)) :
|
||||
nrf_gpiote_task_addr_get(nrf_gpiote_clr_task_get(gpiote_rx_tx_channel));
|
||||
}
|
||||
|
||||
void nrf21540_gpio_trx_enable(nrf21540_trx_t dir)
|
||||
{
|
||||
uint32_t gpiote_task_start = nrf21540_gpio_trx_task_start_address_get(dir, NRF21540_ENABLE);
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_TRX_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_EVENT),
|
||||
gpiote_task_start);
|
||||
nrf_ppi_channel_enable(NRF21540_TRX_PPI_CHANNEL);
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_gpio_pwr_mode_set(nrf21540_pwr_mode_t mode)
|
||||
{
|
||||
if (mode == NRF21540_PWR_MODE_A)
|
||||
{
|
||||
nrf_gpio_pin_clear(NRF21540_MODE_PIN);
|
||||
}
|
||||
else if (mode == NRF21540_PWR_MODE_B)
|
||||
{
|
||||
nrf_gpio_pin_set(NRF21540_MODE_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /*NRF21540_USE_GPIO_MANAGEMENT*/
|
||||
97
components/drivers_ext/nrf21540/nrf21540_gpio.h
Normal file
97
components/drivers_ext/nrf21540/nrf21540_gpio.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF21540_GPIO_H_
|
||||
#define NRF21540_GPIO_H_
|
||||
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf21540_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Function initializes GPIO interface.
|
||||
*/
|
||||
void nrf21540_gpio_init(void);
|
||||
|
||||
/**@brief Function choses one of two physical antenna outputs.
|
||||
*
|
||||
* @param[in] antenna one of antenna outputs. See @ref nrf21540_antenna_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_gpio_ant_set(nrf21540_antenna_t antenna);
|
||||
|
||||
#if NRF21540_USE_GPIO_MANAGEMENT
|
||||
/**@brief Function returns address of task which triggers RX_EN/TX_EN pin
|
||||
* to set nRF21540 radio trasfer direction.
|
||||
*
|
||||
* @param[in] dir Direction of the radio transmission. See @ref nrf21540_trx_t.
|
||||
* @param[in] required_state State of RX/TX transfer. See @ref nrf21540_bool_state_t.
|
||||
* @return Address of appropriate task.
|
||||
*/
|
||||
uint32_t nrf21540_gpio_trx_task_start_address_get(nrf21540_trx_t dir,
|
||||
nrf21540_bool_state_t required_state);
|
||||
|
||||
/**@brief Function configures the chip and peripherals for TX/RX transfer purpose.
|
||||
*
|
||||
* @details enables/disables RX/TX transfers.
|
||||
*
|
||||
* @param[in] dir direction of radio transfer. See @ref nrf21540_trx_t.
|
||||
*/
|
||||
void nrf21540_gpio_trx_enable(nrf21540_trx_t dir);
|
||||
|
||||
/**@brief Function choses one of two predefined power modes in nRF21540.
|
||||
*
|
||||
* @details Refer to nRF21540 Objective Product Specification, section: TX power control.
|
||||
*
|
||||
* @param[in] mode Power mode. See @ref nrf21540_pwr_mode_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_gpio_pwr_mode_set(nrf21540_pwr_mode_t mode);
|
||||
|
||||
#endif /*NRF21540_USE_GPIO_MANAGEMENT*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_GPIO_H_
|
||||
125
components/drivers_ext/nrf21540/nrf21540_macro.h
Normal file
125
components/drivers_ext/nrf21540/nrf21540_macro.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF21540_MACRO_H_
|
||||
#define NRF21540_MACRO_H_
|
||||
|
||||
#include "nrf21540_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@brief Macro for retrieving the state of the nRF21540 radio event. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_EVENT_CHECK(event) \
|
||||
nrf_radio_event_check(event)
|
||||
#else
|
||||
#define NRF21540_RADIO_EVENT_CHECK(event) \
|
||||
nrf_egu_event_check(NRF21540_EGU, event)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for clearing the nRF21540 radio event. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_EVENT_CLEAR(event) \
|
||||
nrf_radio_event_clear(event)
|
||||
#else
|
||||
#define NRF21540_RADIO_EVENT_CLEAR(event) \
|
||||
nrf_egu_event_clear(NRF21540_EGU, event)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for triggering the nRF21540 radio task. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_TASK_TRIGGER(task) \
|
||||
nrf_radio_task_trigger(event)
|
||||
#else
|
||||
#define NRF21540_RADIO_TASK_TRIGGER(task) \
|
||||
nrf_egu_task_trigger(NRF21540_EGU, event)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for disabling the nRF21540 interrupts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_INT_DISABLE(mask) \
|
||||
nrf_radio_int_disable(mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_INT_DISABLE(mask) \
|
||||
nrf_egu_int_disable(NRF21540_EGU, mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for enabling the nRF21540 interrupts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_INT_ENABLE(mask) \
|
||||
nrf_radio_int_enable(mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_INT_ENABLE(mask) \
|
||||
nrf_egu_int_enable(NRF21540_EGU, mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for enabling the nRF21540 shorts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE(shorts_mask) \
|
||||
nrf_radio_shorts_enable(shorts_mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE(shorts_mask) \
|
||||
(m_nrf21540_data.shorts |= shorts_mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for disabling the nRF21540 shorts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_SHORTS_DISABLE(shorts_mask) \
|
||||
nrf_radio_shorts_disable(shorts_mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_SHORTS_DISABLE(shorts_mask) \
|
||||
(m_nrf21540_data.shorts &= ~shorts_mask)
|
||||
#endif
|
||||
|
||||
/**@brief Macro for disabling the nRF21540 shorts. */
|
||||
#if !NRF21540_DO_NOT_USE_NATIVE_RADIO_IRQ_HANDLER
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE_CHECK(shorts_mask) \
|
||||
(nrf_radio_shorts_get() && shorts_mask)
|
||||
#else
|
||||
#define NRF21540_RADIO_SHORTS_ENABLE_CHECK(shorts_mask) \
|
||||
(m_nrf21540_data.shorts && shorts_mask)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_MACRO_H_
|
||||
269
components/drivers_ext/nrf21540/nrf21540_spi.c
Normal file
269
components/drivers_ext/nrf21540/nrf21540_spi.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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 "nrf21540_spi.h"
|
||||
#include <string.h>
|
||||
#include "nrf_assert.h"
|
||||
#include "boards.h"
|
||||
#include "nrf_ppi.h"
|
||||
#include "nrf21540_defs.h"
|
||||
#include "nrf_timer.h"
|
||||
|
||||
#if NRF21540_USE_SPI_MANAGEMENT
|
||||
|
||||
static uint8_t m_spi_tx_data[NRF21540_SPI_LENGTH_BYTES]; ///< SPI tx buffer.
|
||||
static uint8_t m_spi_rx_data[NRF21540_SPI_LENGTH_BYTES]; ///< SPI rx buffer.
|
||||
static volatile bool m_spi_xfer_done; ///< Flag indicates that SPI completed the transfer.
|
||||
|
||||
/**@brief Structure keeps content of important registers of nRF21540.
|
||||
*
|
||||
* @details Driver keeps this data because it needs to operate at single bits
|
||||
* included in these registers (otherwise it should read it content
|
||||
* during every operation).
|
||||
*/
|
||||
|
||||
static struct {
|
||||
uint8_t CONFREG0; ///< CONFREG0 register's content.
|
||||
uint8_t CONFREG1; ///< CONFREG1 register's content.
|
||||
} m_confreg_statics;
|
||||
|
||||
static const nrfx_spim_t spi = NRFX_SPIM_INSTANCE(NRF21540_SPIM_NO); /**< SPI instance. */
|
||||
|
||||
/**@brief Function waits for SPI transfer has finished
|
||||
*
|
||||
* @details Used in blocking mode transfer
|
||||
*/
|
||||
static inline void wait_for_transfer_end(void)
|
||||
{
|
||||
while (!m_spi_xfer_done)
|
||||
{}
|
||||
m_spi_xfer_done = false;
|
||||
}
|
||||
|
||||
/**@brief Handler called by nrfx driver when SPI event occurs.
|
||||
*
|
||||
* @param[in] p_event Event which triggers the handler.
|
||||
* @param[in] p_context Context.
|
||||
*/
|
||||
static void spim_event_handler(nrfx_spim_evt_t const *p_event, void *p_context)
|
||||
{
|
||||
m_spi_xfer_done = true;
|
||||
}
|
||||
|
||||
/**@brief Function reads the content of nRF21540 chip register.
|
||||
*
|
||||
* @details Preparation of read register operation. Every register has one byte size.
|
||||
*
|
||||
* @param[in] reg Register address to read.
|
||||
* @param[in] mode if NRF21540_EXEC_MODE_BLOCKING the function will wait for data
|
||||
* received.
|
||||
* @param[in] start_now if enabled, transmision immediately initialized,
|
||||
* otherwise transfer will be triggered by external event.
|
||||
*/
|
||||
static uint8_t spi_reg_read(nrf21540_reg_t reg, nrf21540_execution_mode_t mode, bool start_now)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && start_now == false));
|
||||
nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_spi_tx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES,
|
||||
m_spi_rx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES);
|
||||
m_spi_tx_data[NRF21540_SPI_COMMAND_ADDR_BYTE] =
|
||||
(NRF21540_SPI_COMMAND_READ << NRF21540_SPI_COMMAND_Pos) | (reg << NRF21540_SPI_REG_Pos);
|
||||
(void)nrfx_spim_xfer(&spi, &xfer_desc, 0);
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
wait_for_transfer_end();
|
||||
}
|
||||
return m_spi_rx_data[NRF21540_SPI_DATA_BYTE];
|
||||
}
|
||||
|
||||
/**@brief Function writes the content of nRF21540 chip register.
|
||||
*
|
||||
* @details Preparation of data to send. Every register has one byte size.
|
||||
*
|
||||
* @param[in] reg Register address to write.
|
||||
* @param[in] data Data to write.
|
||||
* @param[in] mode if NRF21540_EXEC_MODE_BLOCKING the function will wait for transfer
|
||||
* finished after sending data.
|
||||
* @param[in] start_now if enabled, transmision immediately initialized,
|
||||
* otherwise transfer will be triggered by external event.
|
||||
*/
|
||||
static void spi_reg_write(nrf21540_reg_t reg, uint8_t data, nrf21540_execution_mode_t mode, bool start_now)
|
||||
{
|
||||
ASSERT(!(mode == NRF21540_EXEC_MODE_BLOCKING && start_now == false));
|
||||
nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_spi_tx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES,
|
||||
m_spi_rx_data,
|
||||
NRF21540_SPI_LENGTH_BYTES);
|
||||
m_spi_tx_data[NRF21540_SPI_COMMAND_ADDR_BYTE] =
|
||||
(NRF21540_SPI_COMMAND_WRITE << NRF21540_SPI_COMMAND_Pos) | (reg << NRF21540_SPI_REG_Pos);
|
||||
m_spi_tx_data[NRF21540_SPI_DATA_BYTE] = data;
|
||||
uint32_t flags = start_now ? 0 : NRFX_SPIM_FLAG_HOLD_XFER;
|
||||
(void)nrfx_spim_xfer(&spi, &xfer_desc, flags);
|
||||
if (mode == NRF21540_EXEC_MODE_BLOCKING)
|
||||
{
|
||||
wait_for_transfer_end();
|
||||
}
|
||||
}
|
||||
|
||||
/**@brief Function reads content of important nRF21540's registers and stores
|
||||
* it to dedicated structure (@ref m_confreg_statics).
|
||||
*
|
||||
* @return Return NRF based error code.
|
||||
*/
|
||||
static ret_code_t m_confreg_statics_content_update(void)
|
||||
{
|
||||
ret_code_t ret = nrf21540_pdn_drive(true, NRF21540_EXEC_MODE_BLOCKING);
|
||||
if (ret != NRF_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
m_confreg_statics.CONFREG0 = spi_reg_read(NRF21540_REG_CONFREG0,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
m_confreg_statics.CONFREG1 = spi_reg_read(NRF21540_REG_CONFREG1,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
return nrf21540_pdn_drive(false, NRF21540_EXEC_MODE_BLOCKING);
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_spi_init(void)
|
||||
{
|
||||
ret_code_t ret;
|
||||
nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
|
||||
spi_config.frequency = NRF_SPIM_FREQ_4M;
|
||||
spi_config.ss_pin = NRF21540_CS_PIN;
|
||||
spi_config.miso_pin = NRF21540_MISO_PIN;
|
||||
spi_config.mosi_pin = NRF21540_MOSI_PIN;
|
||||
spi_config.sck_pin = NRF21540_CLK_PIN;
|
||||
spi_config.ss_active_high = false;
|
||||
ret = nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL);
|
||||
if (ret != NRFX_SUCCESS)
|
||||
{
|
||||
return NRF_ERROR_INTERNAL;
|
||||
}
|
||||
return m_confreg_statics_content_update();
|
||||
}
|
||||
|
||||
|
||||
/**@brief Function enables or disables nRF21540 TX mode.
|
||||
*
|
||||
* @details Preparation of appropriate register content and tranfer initialization.
|
||||
*
|
||||
* @param[in] state NRF21540_DISABLE/NRF21540_ENABLE causes TX mode disabled/enabled.
|
||||
*/
|
||||
static void tx_en_drive(nrf21540_bool_state_t state)
|
||||
{
|
||||
uint8_t reg_val;
|
||||
if (state == NRF21540_ENABLE)
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG0 | NRF21540_BITS_CONFREG0_TX_EN_Enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG0 &(~NRF21540_BITS_CONFREG0_TX_EN_Enable);
|
||||
}
|
||||
spi_reg_write(NRF21540_REG_CONFREG0, reg_val, NRF21540_EXEC_MODE_NON_BLOCKING, false);
|
||||
}
|
||||
|
||||
/**@brief Function enables or disables nRF21540 RX mode.
|
||||
*
|
||||
* @details Preparation of appropriate register content and tranfer initialization.
|
||||
*
|
||||
* @param[in] state NRF21540_DISABLE/NRF21540_ENABLE causes RX mode disabled/enabled.
|
||||
*/
|
||||
static void rx_en_drive(nrf21540_bool_state_t state)
|
||||
{
|
||||
uint8_t reg_val;
|
||||
if (state == NRF21540_ENABLE)
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG1 | NRF21540_BITS_CONFREG1_RX_EN_Enable;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_val = m_confreg_statics.CONFREG1 &(~NRF21540_BITS_CONFREG1_RX_EN_Disable);
|
||||
}
|
||||
spi_reg_write(NRF21540_REG_CONFREG1, reg_val, NRF21540_EXEC_MODE_NON_BLOCKING, false);
|
||||
}
|
||||
|
||||
inline uint32_t nrf21540_spim_trx_task_start_address_get(void)
|
||||
{
|
||||
return nrfx_spim_start_task_get(&spi);
|
||||
}
|
||||
|
||||
void nrf21540_spim_for_trx_configure(nrf21540_trx_t dir, nrf21540_bool_state_t required_state)
|
||||
{
|
||||
if (dir == NRF21540_TX)
|
||||
{
|
||||
tx_en_drive(required_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
rx_en_drive(required_state);
|
||||
}
|
||||
if (required_state == NRF21540_ENABLE)
|
||||
{
|
||||
uint32_t task_start_address = nrfx_spim_start_task_get(&spi);
|
||||
|
||||
nrf_ppi_channel_endpoint_setup(NRF21540_TRX_PPI_CHANNEL,
|
||||
(uint32_t)nrf_timer_event_address_get(NRF21540_TIMER,
|
||||
NRF21540_TIMER_CC_PD_PG_EVENT),
|
||||
task_start_address);
|
||||
nrf_ppi_channel_enable(NRF21540_TRX_PPI_CHANNEL);
|
||||
}
|
||||
}
|
||||
|
||||
ret_code_t nrf21540_spi_pwr_mode_set(nrf21540_pwr_mode_t mode)
|
||||
{
|
||||
if (mode == NRF21540_PWR_MODE_A)
|
||||
{
|
||||
spi_reg_write(NRF21540_REG_CONFREG0, NRF21540_BITS_CONFREG0_MODE_0,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
}
|
||||
else if (mode == NRF21540_PWR_MODE_B)
|
||||
{
|
||||
spi_reg_write(NRF21540_REG_CONFREG0, NRF21540_BITS_CONFREG0_MODE_1,
|
||||
NRF21540_EXEC_MODE_BLOCKING, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /*NRF21540_USE_SPI_MANAGEMENT*/
|
||||
213
components/drivers_ext/nrf21540/nrf21540_spi.h
Normal file
213
components/drivers_ext/nrf21540/nrf21540_spi.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF21540_SPI_H_
|
||||
#define NRF21540_SPI_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "nrfx_spim.h"
|
||||
#include "nrf21540_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief nRF21540 SPI interface parameters defines.
|
||||
*/
|
||||
#define NRF21540_SPI_LENGTH_BYTES 2 ///< SPI tx/rx buffer size in bytes.
|
||||
#define NRF21540_SPI_COMMAND_ADDR_BYTE 0 ///< Position of command field in SPI frame.
|
||||
#define NRF21540_SPI_DATA_BYTE 1 ///< Position of data field in SPI frame.
|
||||
#define NRF21540_SPI_COMMAND_Pos 6 ///< Command code bit-position in command field.
|
||||
#define NRF21540_SPI_REG_Pos 0 ///< Register address bit-position in command field.
|
||||
#define NRF21540_SPI_COMMAND_NOP 0x00 ///< 'NOP' command code.
|
||||
#define NRF21540_SPI_COMMAND_READ 0x02 ///< 'READ' command code.
|
||||
#define NRF21540_SPI_COMMAND_WRITE 0x03 ///< 'WRITE' command code.
|
||||
|
||||
/**@brief CONFREG0 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Pos 0 ///< Position of TX_EN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Msk (1 << NRF21540_BITS_CONFREG0_TX_EN_Pos) ///< Bit mask of TX_EN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Disable 0 ///< Disable TX mode.
|
||||
#define NRF21540_BITS_CONFREG0_TX_EN_Enable 1 ///< Enable TX mode.
|
||||
|
||||
#define NRF21540_BITS_CONFREG0_MODE_Pos 1 ///< Position of MODE field.
|
||||
#define NRF21540_BITS_CONFREG0_MODE_Msk (1 << NRF21540_BITS_CONFREG0_MODE_Pos) ///< Bit mask of MODE field.
|
||||
#define NRF21540_BITS_CONFREG0_MODE_0 0 ///< Selects MODE 0.
|
||||
#define NRF21540_BITS_CONFREG0_MODE_1 1 ///< Selects MODE 1.
|
||||
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Pos 2 ///< Position of TX_GAIN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Msk (0x1F << NRF21540_BITS_CONFREG0_TX_GAIN_Pos) ///< Bit mask of TX_GAIN field.
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Min 0 ///< Minimum TX_GAIN register value
|
||||
#define NRF21540_BITS_CONFREG0_TX_GAIN_Max 31 ///< Maximum TX_GAIN register value
|
||||
|
||||
/**@brief CONFREG1 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Pos 0 ///< Position of RX_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Msk (1 << NRF21540_BITS_CONFREG1_RX_EN_Pos) ///< Bit mask of TX_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Disable 0 ///< Disable RX mode.
|
||||
#define NRF21540_BITS_CONFREG1_RX_EN_Enable 1 ///< Enable RX mode.
|
||||
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Pos 2 ///< Position of UICR_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Msk (1 << NRF21540_BITS_CONFREG1_UICR_EN_Pos) ///< Bit mask of UICR_EN field.
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Disable 0 ///< Disable UICR program mode.
|
||||
#define NRF21540_BITS_CONFREG1_UICR_EN_Enable 1 ///< Enable UICR program mode.
|
||||
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Pos 4 ///< Position of KEY field.
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Msk (0x0F << NRF21540_BITS_CONFREG1_KEY_Pos) ///< Bit mask of KEY field.
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Enter 15 ///< Enter UICR program mode.
|
||||
#define NRF21540_BITS_CONFREG1_KEY_Leave 0 ///< Leave UICR program mode.
|
||||
|
||||
/**@brief CONFREG2 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Pos 0 ///< Position of POUTA_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Msk (0x1F << NRF21540_BITS_CONFREG2_POUTA_UICR_Pos) ///< Bit mask of POUTA_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Min 0 ///< Minimum POUTA_UICR register value
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_UICR_Max 31 ///< Maximum POUTA_UICR register value
|
||||
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_Pos 5 ///< Position of POUTA_SEL field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_Msk (1 << NRF21540_BITS_CONFREG2_POUTA_SEL_Pos) ///< Bit mask of POUTA_SEL field.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_PROD 0 ///< Initialize TX_GAIN register with 20dBm value.
|
||||
#define NRF21540_BITS_CONFREG2_POUTA_SEL_UICR 1 ///< Initialize TX_GAIN register with POUTA_UICR value.
|
||||
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_Pos 7 ///< Position of WR_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_Msk (1 << NRF21540_BITS_CONFREG2_WR_UICR_Pos) ///< Bit mask of WR_UICR field.
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_IDLE 0 ///< EFUSE idle .
|
||||
#define NRF21540_BITS_CONFREG2_WR_UICR_WRITE 1 ///< EFUSE write.
|
||||
|
||||
/**@brief CONFREG3 register bitfields.
|
||||
*/
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Pos 0 ///< Position of POUTB_UICR field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Msk (0x1F << NRF21540_BITS_CONFREG3_POUTB_SEL_Pos) ///< Bit mask of POUTB_UICR field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Min 0 ///< Minimum POUTB_UICR register value
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_UICR_Max 31 ///< Maximum POUTB_UICR register value
|
||||
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_Pos 5 ///< Position of POUTB_SEL field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_Msk (1 << NRF21540_BITS_CONFREG3_POUTB_SEL_Pos) ///< Bit mask of POUTB_SEL field.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_PROD 0 ///< Initialize TX_GAIN register with 20dBm value.
|
||||
#define NRF21540_BITS_CONFREG3_POUTB_SEL_UICR 1 ///< Initialize TX_GAIN register with POUTB_UICR value.
|
||||
|
||||
/**@brief PARTNUMBER register bitfields.
|
||||
*/
|
||||
#define NRF21540_PARTNUMBER_PARTNUMBER_Pos 0 ///< Position of PARTNUMBER field.
|
||||
#define NRF21540_PARTNUMBER_PARTNUMBER_Msk (0xFF << NRF21540_PARTNUMBER_PARTNUMBER_Pos) ///< Bit mask of PARTNUMBER field.
|
||||
|
||||
/**@brief HW_REVISON register bitfields.
|
||||
*/
|
||||
#define NRF21540_HW_REVISON_HW_REVISION_Pos 4 ///< Position of HW_REVISON field.
|
||||
#define NRF21540_HW_REVISON_HW_REVISION_Msk (0xF << NRF21540_HW_REVISON_HW_REVISION_Pos) ///< Bit mask of HW_REVISON field.
|
||||
|
||||
/**@brief HW_ID0 register bitfields.
|
||||
*/
|
||||
#define NRF21540_HW_ID0_Pos 0 ///< Position of HW_ID0 field.
|
||||
#define NRF21540_HW_ID0_Msk (0xFF << NRF21540_HW_ID0_Pos) ///< Bit mask of HW_ID0 field.
|
||||
|
||||
/**@brief HW_ID1 register bitfields.
|
||||
*/
|
||||
#define NRF21540_HW_ID1_Pos 0 ///< Position of HW_ID1 field.
|
||||
#define NRF21540_HW_ID1_Msk (0xFF << NRF21540_HW_ID1_Pos) ///< Bit mask of HW_ID1 field.
|
||||
|
||||
/**@brief nRF21540 internal registers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_REG_CONFREG0 = 0x00, ///< CONFREG0 register address.
|
||||
NRF21540_REG_CONFREG1 = 0x01, ///< CONFREG1 register address.
|
||||
NRF21540_REG_CONFREG2 = 0x02, ///< CONFREG2 register address.
|
||||
NRF21540_REG_CONFREG3 = 0x03, ///< CONFREG3 register address.
|
||||
NRF21540_REG_PARTNUMBER = 0x14, ///< PARTNUMBER register address.
|
||||
NRF21540_REG_HW_REVISION = 0x15, ///< HW_REVISION register address.
|
||||
NRF21540_REG_HW_ID0 = 0x16, ///< HW_ID0 register address.
|
||||
NRF21540_REG_HW_ID1 = 0x17, ///< HW_ID1 register address.
|
||||
} nrf21540_reg_t;
|
||||
|
||||
/**@brief Function initializes SPI interface.
|
||||
*
|
||||
* @return NRF_ERROR_INTERNAL when SPIM driver initialization error occured.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_spi_init(void);
|
||||
|
||||
/**@brief Function returns address of task which triggers SPI transfer.
|
||||
*
|
||||
* @return address of appropriate task.
|
||||
*/
|
||||
uint32_t nrf21540_spim_trx_task_start_address_get(void);
|
||||
|
||||
/**@brief Function configures the chip and peripherals for TX/RX transfer purpose.
|
||||
*
|
||||
* @details It can enable/disable RX/TX transfers.
|
||||
*
|
||||
* @param[in] dir Direction of the radio transmission. See @ref nrf21540_trx_t.
|
||||
* @param[in] required_state State of RX/TX transfer. See @ref nrf21540_bool_state_t.
|
||||
* chosen transfer type.
|
||||
*/
|
||||
void nrf21540_spim_for_trx_configure(nrf21540_trx_t dir, nrf21540_bool_state_t required_state);
|
||||
|
||||
/**@brief Function choses one of predefined power modes in nRF21540.
|
||||
*
|
||||
* @details Refer to nRF21540 Objective Product Specification, section: TX power control.
|
||||
*
|
||||
* @param[in] mode Power mode. See @ref nrf21540_pwr_mode_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_spi_pwr_mode_set(nrf21540_pwr_mode_t mode);
|
||||
|
||||
/**@brief Function sets nRF21540 power state by driving PDN pin.
|
||||
*
|
||||
* @param[in] state Required PDN pin state.
|
||||
* @param[in] mode Execution mode. See @ref nrf21540_execution_mode_t.
|
||||
* @return NRF_ERROR_INVALID_PARAM when invalid argument given.
|
||||
* NRF_ERROR_INVALID_STATE when nRF21540's state isn't proper
|
||||
* to perform the operation (@sa nrf21540_state_t).
|
||||
* NRF_ERROR_INTERNAL when driver is in error state.
|
||||
* Reinitialization is required.
|
||||
* NRF_SUCCESS on success.
|
||||
*/
|
||||
ret_code_t nrf21540_pdn_drive(bool state, nrf21540_execution_mode_t mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_SPI_H_
|
||||
111
components/drivers_ext/nrf21540/nrf21540_types.h
Normal file
111
components/drivers_ext/nrf21540/nrf21540_types.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef NRF21540_TYPES_H_
|
||||
#define NRF21540_TYPES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* @defgroup nrf21540_types nRF21540 front-end Bluetooth range extender types
|
||||
* @{
|
||||
* @ingroup nrf21540
|
||||
*/
|
||||
|
||||
/**@brief Value used as event zero-address - for immediate function execution.
|
||||
* This is useful in functions with 'user_trigger_event' input parameter.
|
||||
*/
|
||||
#define NRF21540_EXECUTE_NOW ((uint32_t)0)
|
||||
|
||||
/**@brief nRF21540 antenna outputs.
|
||||
*
|
||||
* @note Read more in the Product Specification.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_ANT1, ///< Antenna 1 output.
|
||||
NRF21540_ANT2 ///< Antenna 2 output.
|
||||
} nrf21540_antenna_t;
|
||||
|
||||
|
||||
/**@brief nRF21540 power modes.
|
||||
*
|
||||
* @note Read more in the Product Specification.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_PWR_MODE_A, ///< Power mode A.
|
||||
NRF21540_PWR_MODE_B ///< Power mode B.
|
||||
} nrf21540_pwr_mode_t;
|
||||
|
||||
|
||||
/**@brief nRF21540 transmission direction modes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_TX, ///< Transmission direction mode transmit.
|
||||
NRF21540_RX ///< Transmission direction mode receive.
|
||||
} nrf21540_trx_t;
|
||||
|
||||
/**@brief State type for nRF21540 purposes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_DISABLE, ///< State disable.
|
||||
NRF21540_ENABLE ///< State enable.
|
||||
} nrf21540_bool_state_t;
|
||||
|
||||
/**@brief Modes (blocking/non-blocking) for nRF21540 purposes.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NRF21540_EXEC_MODE_NON_BLOCKING, ///< Non-blocking execution mode.
|
||||
NRF21540_EXEC_MODE_BLOCKING ///< Blocking execution mode.
|
||||
} nrf21540_execution_mode_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NRF21540_TYPES_H_
|
||||
305
components/drivers_ext/nrf6350/nrf6350.c
Normal file
305
components/drivers_ext/nrf6350/nrf6350.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/**
|
||||
* Copyright (c) 2008 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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" */
|
||||
154
components/drivers_ext/nrf6350/nrf6350.h
Normal file
154
components/drivers_ext/nrf6350/nrf6350.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Copyright (c) 2012 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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_
|
||||
/** @} */
|
||||
749
components/drivers_ext/pcal6408a/pcal6408a.c
Normal file
749
components/drivers_ext/pcal6408a/pcal6408a.c
Normal file
@@ -0,0 +1,749 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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 "pcal6408a.h"
|
||||
|
||||
static pcal6408a_instance_t * m_p_instances;
|
||||
static uint8_t m_max_instance_count;
|
||||
static uint8_t m_added_inst_count;
|
||||
|
||||
#define PCAL6408A_WRITE(p_instance, msg) \
|
||||
nrf_twi_sensor_write(p_instance.p_sensor_data, \
|
||||
p_instance.sensor_addr, \
|
||||
msg, \
|
||||
ARRAY_SIZE(msg), \
|
||||
true)
|
||||
|
||||
#define PCAL6408A_REG_OUTPUT_PORT_DEFAULT_VAL 0xFF
|
||||
#define PCAL6408A_REG_POLARITY_INVERSION_DEFAULT_VAL 0x00
|
||||
#define PCAL6408A_REG_CONFIGURATION_DEFAULT_VAL 0xFF
|
||||
#define PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0_DEFAULT_VAL 0xFF
|
||||
#define PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1_DEFAULT_VAL 0xFF
|
||||
#define PCAL6408A_REG_INPUT_LATCH_DEFAULT_VAL 0x00
|
||||
#define PCAL6408A_REG_PULL_UP_DOWN_ENABLE_DEFAULT_VAL 0x00
|
||||
#define PCAL6408A_REG_PULL_UP_DOWN_SELECT_DEFAULT_VAL 0xFF
|
||||
#define PCAL6408A_REG_INTERRUPT_MASK_DEFAULT_VAL 0xFF
|
||||
#define PCAL6408A_REG_INTERRUPT_STATUS_DEFAULT_VAL 0x00
|
||||
#define PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION_DEFAULT_VAL 0x00
|
||||
|
||||
/**
|
||||
* ================================================================================================
|
||||
* @brief General expander utility functions.
|
||||
*/
|
||||
|
||||
void pcal6408a_init(pcal6408a_instance_t * p_instances, uint8_t count)
|
||||
{
|
||||
ASSERT(p_instances != NULL);
|
||||
m_p_instances = p_instances;
|
||||
m_max_instance_count = count;
|
||||
m_added_inst_count = 0;
|
||||
}
|
||||
|
||||
static void pcal6408a_default_cfg_set(uint8_t instance_num)
|
||||
{
|
||||
m_p_instances[instance_num].registers[1] = PCAL6408A_REG_OUTPUT_PORT_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[2] = PCAL6408A_REG_POLARITY_INVERSION_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[3] = PCAL6408A_REG_CONFIGURATION_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[4] = PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[5] = PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[6] = PCAL6408A_REG_INPUT_LATCH_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[7] = PCAL6408A_REG_PULL_UP_DOWN_ENABLE_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[8] = PCAL6408A_REG_PULL_UP_DOWN_SELECT_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[9] = PCAL6408A_REG_INTERRUPT_MASK_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[10] = PCAL6408A_REG_INTERRUPT_STATUS_DEFAULT_VAL;
|
||||
m_p_instances[instance_num].registers[11] = PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION_DEFAULT_VAL;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_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_added_inst_count >= m_max_instance_count)
|
||||
{
|
||||
return NRF_ERROR_STORAGE_FULL;
|
||||
}
|
||||
|
||||
m_p_instances[m_added_inst_count].p_sensor_data = p_twi_sensor;
|
||||
m_p_instances[m_added_inst_count].sensor_addr = sensor_address;
|
||||
pcal6408a_default_cfg_set(m_added_inst_count);
|
||||
m_added_inst_count++;
|
||||
ret_code_t err_code = pcal6408a_cfg_write(m_added_inst_count - 1);
|
||||
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_cfg_write(uint8_t instance_num)
|
||||
{
|
||||
if (instance_num >= m_added_inst_count)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret_code_t err_code;
|
||||
|
||||
for (uint8_t i = PCAL6408A_REG_OUTPUT_PORT; i <= PCAL6408A_REG_CONFIGURATION; i++)
|
||||
{
|
||||
err_code = nrf_twi_sensor_reg_write(m_p_instances[instance_num].p_sensor_data,
|
||||
m_p_instances[instance_num].sensor_addr,
|
||||
i,
|
||||
&m_p_instances[instance_num].registers[i],
|
||||
1);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (nrf_twi_mngr_is_idle(m_p_instances[instance_num].p_sensor_data->p_twi_mngr) != true)
|
||||
{
|
||||
// Wait for transaction to finish to not overflow msg buffer
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = PCAL6408A_REG_COUNT_SEQUENCE_1; i <= (PCAL6408A_REG_COUNT_ALL - 3); i++)
|
||||
{
|
||||
err_code = nrf_twi_sensor_reg_write(
|
||||
m_p_instances[instance_num].p_sensor_data,
|
||||
m_p_instances[instance_num].sensor_addr,
|
||||
i - PCAL6408A_REG_COUNT_SEQUENCE_1 + PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0,
|
||||
&m_p_instances[instance_num].registers[i],
|
||||
1);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (nrf_twi_mngr_is_idle(m_p_instances[instance_num].p_sensor_data->p_twi_mngr) != true)
|
||||
{
|
||||
// Wait for transaction to finish to not overflow msg buffer
|
||||
}
|
||||
}
|
||||
|
||||
err_code = nrf_twi_sensor_reg_write(
|
||||
m_p_instances[instance_num].p_sensor_data,
|
||||
m_p_instances[instance_num].sensor_addr,
|
||||
PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION,
|
||||
&m_p_instances[instance_num].registers[PCAL6408A_REG_COUNT_ALL - 1],
|
||||
1);
|
||||
|
||||
end:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_cfg_read(uint8_t instance_num)
|
||||
{
|
||||
if (instance_num >= m_added_inst_count)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret_code_t err_code;
|
||||
|
||||
for (uint8_t i = 0; i <= PCAL6408A_REG_CONFIGURATION; i++)
|
||||
{
|
||||
err_code = nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
|
||||
m_p_instances[instance_num].sensor_addr,
|
||||
i,
|
||||
NULL,
|
||||
&m_p_instances[instance_num].registers[i],
|
||||
1);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (nrf_twi_mngr_is_idle(m_p_instances[instance_num].p_sensor_data->p_twi_mngr) != true)
|
||||
{
|
||||
// Wait for transaction to finish to not overflow msg buffer
|
||||
}
|
||||
}
|
||||
|
||||
for(uint8_t i = PCAL6408A_REG_COUNT_SEQUENCE_1; i <= (PCAL6408A_REG_COUNT_ALL - 3); i++)
|
||||
{
|
||||
err_code = nrf_twi_sensor_reg_read(
|
||||
m_p_instances[instance_num].p_sensor_data,
|
||||
m_p_instances[instance_num].sensor_addr,
|
||||
i - PCAL6408A_REG_COUNT_SEQUENCE_1 + PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0,
|
||||
NULL,
|
||||
&m_p_instances[instance_num].registers[i],
|
||||
1);
|
||||
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (nrf_twi_mngr_is_idle(m_p_instances[instance_num].p_sensor_data->p_twi_mngr) != true)
|
||||
{
|
||||
// Wait for transaction to finish to not overflow msg buffer
|
||||
}
|
||||
}
|
||||
|
||||
err_code = nrf_twi_sensor_reg_read(
|
||||
m_p_instances[instance_num].p_sensor_data,
|
||||
m_p_instances[instance_num].sensor_addr,
|
||||
PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION,
|
||||
NULL,
|
||||
&m_p_instances[instance_num].registers[PCAL6408A_REG_COUNT_ALL - 1],
|
||||
1);
|
||||
end:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_pin_data_update(nrf_twi_sensor_reg_cb_t user_cb)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
for (uint8_t i = 0; i < m_added_inst_count - 1; i++)
|
||||
{
|
||||
err_code = nrf_twi_sensor_reg_read(m_p_instances[i].p_sensor_data,
|
||||
m_p_instances[i].sensor_addr,
|
||||
PCAL6408A_REG_INPUT_PORT,
|
||||
NULL,
|
||||
&m_p_instances[i].registers[PCAL6408A_REG_INPUT_PORT],
|
||||
1);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
}
|
||||
return nrf_twi_sensor_reg_read(
|
||||
m_p_instances[m_added_inst_count - 1].p_sensor_data,
|
||||
m_p_instances[m_added_inst_count - 1].sensor_addr,
|
||||
PCAL6408A_REG_INPUT_PORT,
|
||||
user_cb,
|
||||
&m_p_instances[m_added_inst_count - 1].registers[PCAL6408A_REG_INPUT_PORT],
|
||||
1);
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_int_status_update(nrf_twi_sensor_reg_cb_t user_cb)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
for (uint8_t i = 0; i < m_added_inst_count - 1; i++)
|
||||
{
|
||||
err_code = nrf_twi_sensor_reg_read(m_p_instances[i].p_sensor_data,
|
||||
m_p_instances[i].sensor_addr,
|
||||
PCAL6408A_REG_INTERRUPT_STATUS,
|
||||
NULL,
|
||||
&m_p_instances[i].registers[10],
|
||||
1);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
}
|
||||
return nrf_twi_sensor_reg_read(
|
||||
m_p_instances[m_added_inst_count - 1].p_sensor_data,
|
||||
m_p_instances[m_added_inst_count - 1].sensor_addr,
|
||||
PCAL6408A_REG_INTERRUPT_STATUS,
|
||||
user_cb,
|
||||
&m_p_instances[m_added_inst_count - 1].registers[10],
|
||||
1);
|
||||
}
|
||||
|
||||
static uint8_t * get_reg_address(pcal6408a_registers_t reg_addr, uint8_t inst_num)
|
||||
{
|
||||
if (reg_addr <= PCAL6408A_REG_CONFIGURATION)
|
||||
{
|
||||
return &m_p_instances[inst_num].registers[reg_addr];
|
||||
}
|
||||
else if (reg_addr == PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION)
|
||||
{
|
||||
return &m_p_instances[inst_num].registers[PCAL6408A_REG_COUNT_ALL - 1];
|
||||
}
|
||||
else if (reg_addr >= PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0
|
||||
&& reg_addr <= PCAL6408A_REG_INTERRUPT_STATUS)
|
||||
{
|
||||
return &m_p_instances[inst_num].registers[PCAL6408A_REG_COUNT_SEQUENCE_1
|
||||
+ reg_addr
|
||||
- PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_pin_cfg_reg_set(pcal6408a_registers_t reg_addr, uint32_t pin, uint8_t value)
|
||||
{
|
||||
ASSERT(pin <= (PCAL6408A_INNER_PIN_COUNT * m_added_inst_count));
|
||||
|
||||
uint8_t * p_reg_val;
|
||||
uint8_t mask;
|
||||
uint8_t inst_num = pin / PCAL6408A_INNER_PIN_COUNT;
|
||||
|
||||
pin %= PCAL6408A_INNER_PIN_COUNT;
|
||||
|
||||
if (reg_addr == PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0)
|
||||
{
|
||||
if (pin > PCAL6408A_DRIVE_STRENGTH_REG_0_PIN_MAX)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
mask = 3; // Current control register parameter is 2 bits long.
|
||||
pin *= 2;
|
||||
}
|
||||
else if (reg_addr == PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1)
|
||||
{
|
||||
if (pin <= PCAL6408A_DRIVE_STRENGTH_REG_0_PIN_MAX)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
mask = 3; // Current control register parameter is 2 bits long.
|
||||
pin %= PCAL6408A_INNER_PIN_COUNT / 2;
|
||||
pin *= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = 1;
|
||||
}
|
||||
|
||||
p_reg_val = get_reg_address(reg_addr, inst_num);
|
||||
|
||||
if (p_reg_val == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
NRF_TWI_SENSOR_REG_SET(*p_reg_val, (uint8_t) (mask << pin), pin, value);
|
||||
|
||||
uint8_t send_msg[] = {
|
||||
reg_addr,
|
||||
*p_reg_val
|
||||
};
|
||||
|
||||
return PCAL6408A_WRITE(m_p_instances[inst_num], send_msg);
|
||||
}
|
||||
|
||||
uint8_t pcal6408a_pin_cfg_reg_get(pcal6408a_registers_t reg_addr, uint32_t pin)
|
||||
{
|
||||
ASSERT(pin <= (PCAL6408A_INNER_PIN_COUNT * m_added_inst_count));
|
||||
|
||||
uint8_t * p_reg_val;
|
||||
uint8_t mask = 1;
|
||||
uint8_t inst_num = pin / PCAL6408A_INNER_PIN_COUNT;
|
||||
|
||||
pin %= PCAL6408A_INNER_PIN_COUNT;
|
||||
if (reg_addr == PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0
|
||||
|| reg_addr == PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1)
|
||||
{
|
||||
if (pin > PCAL6408A_DRIVE_STRENGTH_REG_0_PIN_MAX)
|
||||
{
|
||||
reg_addr = PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1;
|
||||
pin %= PCAL6408A_INNER_PIN_COUNT / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_addr = PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0;
|
||||
}
|
||||
|
||||
mask = 3; //Current control register parameter is 2 bits long.
|
||||
pin *= 2;
|
||||
}
|
||||
|
||||
p_reg_val = get_reg_address(reg_addr, inst_num);
|
||||
|
||||
if (p_reg_val == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return NRF_TWI_SENSOR_REG_VAL_GET(*p_reg_val, (mask << pin), pin);
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_port_cfg_reg_set(pcal6408a_registers_t reg_addr,
|
||||
uint32_t port,
|
||||
uint8_t mask,
|
||||
pcal6408a_port_op_t flag)
|
||||
{
|
||||
if (port >= m_added_inst_count)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
uint8_t * p_reg_val;
|
||||
uint8_t inst_num = port;
|
||||
|
||||
p_reg_val = get_reg_address(reg_addr, inst_num);
|
||||
|
||||
if (p_reg_val == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (flag)
|
||||
{
|
||||
case PCAL6408A_PORT_WRITE:
|
||||
*p_reg_val = mask;
|
||||
break;
|
||||
case PCAL6408A_PORT_CLEAR:
|
||||
*p_reg_val &= ~mask;
|
||||
break;
|
||||
case PCAL6408A_PORT_SET:
|
||||
*p_reg_val |= mask;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t send_msg[] = {
|
||||
reg_addr,
|
||||
*p_reg_val
|
||||
};
|
||||
|
||||
return PCAL6408A_WRITE(m_p_instances[inst_num], send_msg);
|
||||
}
|
||||
|
||||
uint8_t pcal6408a_port_cfg_reg_get(pcal6408a_registers_t reg_addr, uint32_t port)
|
||||
{
|
||||
ASSERT(port < m_added_inst_count);
|
||||
|
||||
uint8_t inst_num = port;
|
||||
uint8_t * p_reg_val;
|
||||
|
||||
p_reg_val = get_reg_address(reg_addr, inst_num);
|
||||
|
||||
if (p_reg_val == NULL)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return *p_reg_val;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_pin_cfg_drive_strength(uint32_t pin_number,
|
||||
pcal6408a_pin_drive_strength_t drive_strength_config)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
|
||||
if ((pin_number % PCAL6408A_INNER_PIN_COUNT) <= PCAL6408A_DRIVE_STRENGTH_REG_0_PIN_MAX)
|
||||
{
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0,
|
||||
pin_number,
|
||||
drive_strength_config);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1,
|
||||
pin_number,
|
||||
drive_strength_config);
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_port_cfg_drive_strength(uint32_t port_number,
|
||||
uint16_t drive_strength_mask,
|
||||
pcal6408a_port_op_t flag)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0,
|
||||
port_number,
|
||||
(uint8_t)drive_strength_mask, flag);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return err_code;
|
||||
}
|
||||
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1,
|
||||
port_number,
|
||||
(uint8_t)(drive_strength_mask >> 8), flag);
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ===============================================================================================
|
||||
* @brief Functions compatible with nrf_gpio
|
||||
*/
|
||||
|
||||
ret_code_t pcal6408a_pin_cfg_input(uint32_t pin_number, pcal6408a_pin_pull_t pull_config)
|
||||
{
|
||||
ret_code_t err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
pin_number,
|
||||
PCAL6408A_PIN_DIR_INPUT);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (pull_config)
|
||||
{
|
||||
case PCAL6408A_PIN_NOPULL:
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_ENABLE, pin_number, 0);
|
||||
break;
|
||||
|
||||
case PCAL6408A_PIN_PULLDOWN:
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_ENABLE, pin_number, 1);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_SELECT, pin_number, 0);
|
||||
break;
|
||||
|
||||
case PCAL6408A_PIN_PULLUP:
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_ENABLE, pin_number, 1);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
err_code = pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_SELECT, pin_number, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
end:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
|
||||
{
|
||||
if (pin_range_start > pin_range_end)
|
||||
{
|
||||
return NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
uint8_t start_port = pin_range_start / PCAL6408A_INNER_PIN_COUNT;
|
||||
uint8_t end_port = pin_range_end / PCAL6408A_INNER_PIN_COUNT;
|
||||
uint8_t range_value;
|
||||
ret_code_t err_code;
|
||||
|
||||
if (start_port == end_port)
|
||||
{
|
||||
range_value = (0xFF >> (PCAL6408A_INNER_PIN_COUNT - pin_range_end - 1)) &
|
||||
(0xFF << pin_range_start);
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
start_port,
|
||||
range_value,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
range_value = 0xFF << pin_range_start;
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
start_port,
|
||||
range_value,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
range_value = 0xFF >> (PCAL6408A_INNER_PIN_COUNT - pin_range_end - 1);
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
start_port,
|
||||
range_value,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
range_value = 0xFF;
|
||||
for (uint8_t i = (start_port + 1); i < end_port; i++)
|
||||
{
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
i,
|
||||
range_value,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
static ret_code_t pcal6408a_port_pull_cfg_set(uint32_t port,
|
||||
uint8_t mask,
|
||||
pcal6408a_pin_pull_t pull_config)
|
||||
{
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
switch (pull_config)
|
||||
{
|
||||
case PCAL6408A_PIN_NOPULL:
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_ENABLE,
|
||||
port,
|
||||
mask,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
break;
|
||||
|
||||
case PCAL6408A_PIN_PULLDOWN:
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_ENABLE,
|
||||
port,
|
||||
mask,
|
||||
PCAL6408A_PORT_SET);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_SELECT,
|
||||
port,
|
||||
mask,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
break;
|
||||
|
||||
case PCAL6408A_PIN_PULLUP:
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_ENABLE,
|
||||
port,
|
||||
mask,
|
||||
PCAL6408A_PORT_SET);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_PULL_UP_DOWN_SELECT,
|
||||
port,
|
||||
mask,
|
||||
PCAL6408A_PORT_SET);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
ret_code_t pcal6408a_range_cfg_input(uint32_t pin_range_start,
|
||||
uint32_t pin_range_end,
|
||||
pcal6408a_pin_pull_t pull_config)
|
||||
{
|
||||
if (pin_range_start > pin_range_end)
|
||||
{
|
||||
return NRF_ERROR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
uint8_t start_port = pin_range_start / PCAL6408A_INNER_PIN_COUNT;
|
||||
uint8_t end_port = pin_range_end / PCAL6408A_INNER_PIN_COUNT;
|
||||
uint8_t range_value;
|
||||
ret_code_t err_code = NRF_SUCCESS;
|
||||
|
||||
if (start_port == end_port)
|
||||
{
|
||||
range_value = (0xFF >> (PCAL6408A_INNER_PIN_COUNT - pin_range_end - 1))
|
||||
& (0xFF << pin_range_start);
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
start_port,
|
||||
range_value,
|
||||
PCAL6408A_PORT_SET);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
err_code = pcal6408a_port_pull_cfg_set(start_port, range_value, pull_config);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
range_value = 0xFF << pin_range_start;
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
start_port,
|
||||
range_value,
|
||||
PCAL6408A_PORT_SET);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
err_code = pcal6408a_port_pull_cfg_set(start_port, range_value, pull_config);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
range_value = 0xFF >> (PCAL6408A_INNER_PIN_COUNT - pin_range_end - 1);
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
end_port,
|
||||
range_value,
|
||||
PCAL6408A_PORT_SET);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
err_code = pcal6408a_port_pull_cfg_set(end_port, range_value, pull_config);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
range_value = 0xFF;
|
||||
for (uint8_t i = (start_port + 1); i < end_port; i++)
|
||||
{
|
||||
err_code = pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
i,
|
||||
range_value,
|
||||
PCAL6408A_PORT_SET);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
err_code = pcal6408a_port_pull_cfg_set(i, range_value, pull_config);
|
||||
if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
745
components/drivers_ext/pcal6408a/pcal6408a.h
Normal file
745
components/drivers_ext/pcal6408a/pcal6408a.h
Normal file
@@ -0,0 +1,745 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef PCAL6408A_H__
|
||||
#define PCAL6408A_H__
|
||||
|
||||
#include "nrf_twi_sensor.h"
|
||||
#include "pcal6408a_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup pcal6408a_driver PCAL6408A Driver
|
||||
* @ingroup ext_drivers
|
||||
*
|
||||
* @brief Module for configuring and using PCAL6408A GPIO expander.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief First possible expander address.
|
||||
*/
|
||||
#define PCAL6408A_BASE_ADDRESS_FIRST 0x20u
|
||||
/**
|
||||
* @brief Second possible expander address.
|
||||
*/
|
||||
#define PCAL6408A_BASE_ADDRESS_SECOND 0x21u
|
||||
|
||||
/**
|
||||
* @brief Device registers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_REG_INPUT_PORT = 0x00,
|
||||
PCAL6408A_REG_OUTPUT_PORT = 0x01,
|
||||
PCAL6408A_REG_POLARITY_INVERSION = 0x02,
|
||||
PCAL6408A_REG_CONFIGURATION = 0x03,
|
||||
PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_0 = 0x40,
|
||||
PCAL6408A_REG_OUTPUT_DRIVE_STRENGTH_1 = 0x41,
|
||||
PCAL6408A_REG_INPUT_LATCH = 0x42,
|
||||
PCAL6408A_REG_PULL_UP_DOWN_ENABLE = 0x43,
|
||||
PCAL6408A_REG_PULL_UP_DOWN_SELECT = 0x44,
|
||||
PCAL6408A_REG_INTERRUPT_MASK = 0x45,
|
||||
PCAL6408A_REG_INTERRUPT_STATUS = 0x46,
|
||||
PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION = 0x4F
|
||||
} pcal6408a_registers_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for setting the direction of a pin.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PIN_DIR_OUTPUT, /**< Output. */
|
||||
PCAL6408A_PIN_DIR_INPUT /**< Input. */
|
||||
} pcal6408a_pin_dir_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for setting the direction of a port.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PORT_DIR_OUTPUT = 0x00, /**< Output. */
|
||||
PCAL6408A_PORT_DIR_INPUT = 0xFF /**< Input. */
|
||||
} pcal6408a_port_dir_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for setting the state of a pin configured as an output.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PIN_CLR, /**< Clear. */
|
||||
PCAL6408A_PIN_SET /**< Set. */
|
||||
} pcal6408a_pin_set_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for selecting the pin to be pulled down or up.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PIN_NOPULL, /**< No pull. */
|
||||
PCAL6408A_PIN_PULLDOWN, /**< Pin pulldown resistor enabled. */
|
||||
PCAL6408A_PIN_PULLUP /**< Pin pullup resistor enabled. */
|
||||
} pcal6408a_pin_pull_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for selecting the operation for a port.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PORT_WRITE, /**< Mask is written to the port. */
|
||||
PCAL6408A_PORT_CLEAR, /**< Positive bits in mask are cleared in port. */
|
||||
PCAL6408A_PORT_SET /**< Positive bits in mask are set in port. */
|
||||
} pcal6408a_port_op_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for setting the drive strength of a pin.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PIN_25_DRIVE_STRENGTH, /**< Drive strength set to 25% of current drive capability. */
|
||||
PCAL6408A_PIN_50_DRIVE_STRENGTH, /**< Drive strength set to 50% of current drive capability. */
|
||||
PCAL6408A_PIN_75_DRIVE_STRENGTH, /**< Drive strength set to 75% of current drive capability. */
|
||||
PCAL6408A_PIN_100_DRIVE_STRENGTH /**< Drive strength set to 100% of current drive capability. */
|
||||
} pcal6408a_pin_drive_strength_t;
|
||||
|
||||
/**
|
||||
* @brief Enumerator used for setting push-pull or open-drain I/O stage for a port.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PCAL6408A_PORT_PUSH_PULL, /**< Push-pull I/O stage. */
|
||||
PCAL6408A_PORT_OPEN_DRAIN /**< Open-drain I/O stage. */
|
||||
} pcal6408a_port_io_stage_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Macro that defines expander module.
|
||||
*
|
||||
* @param[in] pcal6408a_inst_name Name of the instance to be created.
|
||||
* @param[in] instance_count Number of connected expanders.
|
||||
*/
|
||||
#define PCAL6408A_INSTANCES_DEF_START(pcal6408a_inst_name, instance_count) \
|
||||
static pcal6408a_instance_t pcal6408a_inst_name[instance_count]
|
||||
|
||||
/**
|
||||
* @brief Macro that converts absolute pin number to pin number dependent on number of expander.
|
||||
*
|
||||
* @param[in] pin_num Absolute pin number ranging from 0 to 7.
|
||||
* @param[in] instance_num Number of expander, order is the same as pcal6408a_add_instance calls.
|
||||
*/
|
||||
#define PIN_NUM_CONVERT(pin_num, instance_num) \
|
||||
(pin_num + instance_num * PCAL6408A_INNER_PIN_COUNT)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function initialising expander module.
|
||||
*
|
||||
* @param[in] p_instances Pointer to expander module.
|
||||
* @param[in] count Number of connected expanders.
|
||||
*/
|
||||
void pcal6408a_init(pcal6408a_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 If expander module wasn't initialised
|
||||
* @retval NRF_ERROR_STORAGE_FULL If trying to add more instances than defined.
|
||||
* @retval other Error code from nrf_twi_sensor
|
||||
* @ref nrf_twi_sensor_write
|
||||
*/
|
||||
ret_code_t pcal6408a_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 pcal6408a_add_instance calls.
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_PARAM If there is no expander with given number.
|
||||
* @retval other Error code from nrf_twi_sensor @ref nrf_twi_sensor_write
|
||||
*/
|
||||
ret_code_t pcal6408a_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 pcal6408a_add_instance calls.
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_PARAM If there is no expander with given number.
|
||||
* @retval other Error code from nrf_twi_sensor @ref nrf_twi_sensor_write
|
||||
*/
|
||||
ret_code_t pcal6408a_cfg_read(uint8_t instance_num);
|
||||
|
||||
/**
|
||||
* @brief Function for setting register configuration of a single pin.
|
||||
*
|
||||
* @param[in] reg_addr Register address.
|
||||
* @param[in] pin Pin number.
|
||||
* @param[in] value Value to set.
|
||||
*
|
||||
* @return Error code from nrf_twi_sensor @ref nrf_twi_sensor_write
|
||||
*/
|
||||
ret_code_t pcal6408a_pin_cfg_reg_set(pcal6408a_registers_t reg_addr, uint32_t pin, uint8_t value);
|
||||
|
||||
/**
|
||||
* @brief Function for getting register configuration of a single pin.
|
||||
*
|
||||
* @param[in] reg_addr Register address.
|
||||
* @param[in] pin Pin number.
|
||||
*
|
||||
* @return Pin configuration value
|
||||
*/
|
||||
uint8_t pcal6408a_pin_cfg_reg_get(pcal6408a_registers_t reg_addr, uint32_t pin);
|
||||
|
||||
/**
|
||||
* @brief Function for setting register configuration of a port.
|
||||
*
|
||||
* @param[in] reg_addr Register address.
|
||||
* @param[in] port Port number.
|
||||
* @param[in] mask Mask for the operation.
|
||||
* @param[in] flag Operation, whether mask should be written into register,
|
||||
* values should be cleared or set @ref pcal6408a_port_op_t
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_PARAM If there is no port with such number or invalid flag operation.
|
||||
* @retval other Error code from nrf_twi_sensor @ref nrf_twi_sensor_write
|
||||
*/
|
||||
ret_code_t pcal6408a_port_cfg_reg_set(pcal6408a_registers_t reg_addr,
|
||||
uint32_t port,
|
||||
uint8_t mask,
|
||||
pcal6408a_port_op_t flag);
|
||||
|
||||
/**
|
||||
* @brief Function for getting register configuration of a port.
|
||||
*
|
||||
* @note When reading input register, it should be updated prior using this function,
|
||||
* with @ref pcal6408a_pin_data_update
|
||||
* When reading interrupt status register, it should be updated prior using this function,
|
||||
* with @ref pcal6408a_int_status_update
|
||||
*
|
||||
* @param[in] reg_addr Register address.
|
||||
* @param[in] port Port number.
|
||||
*
|
||||
* @return Register value
|
||||
*/
|
||||
uint8_t pcal6408a_port_cfg_reg_get(pcal6408a_registers_t reg_addr, 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 pcal6408a_pin_data_update(nrf_twi_sensor_reg_cb_t user_cb);
|
||||
|
||||
/**
|
||||
* @brief Function for updating interrupt status data.
|
||||
*
|
||||
* @param user_cb Function to be called after interrupt status update is done.
|
||||
*
|
||||
* @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
|
||||
*/
|
||||
ret_code_t pcal6408a_int_status_update(nrf_twi_sensor_reg_cb_t user_cb);
|
||||
|
||||
/**
|
||||
* @brief Function for setting polarity inversion of a given pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an input for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] state
|
||||
* @arg true Enables polarity inversion.
|
||||
* @arg false Disables polarity inversion.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_polarity_inversion(uint32_t pin_number, bool state);
|
||||
|
||||
/**
|
||||
* @brief Function for setting interrupt of a given pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an input for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] state
|
||||
* @arg true Disables interrupt.
|
||||
* @arg false Enables interrupt.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_interrupt(uint32_t pin_number, bool state);
|
||||
|
||||
/**
|
||||
* @brief Function for setting input latch of a given pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an input for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] state
|
||||
* @arg true Enables input latch.
|
||||
* @arg false Disables input latch.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_latch(uint32_t pin_number, bool state);
|
||||
|
||||
/**
|
||||
* @brief Function for setting drive strength for a given pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an output for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] drive_strength_config Drive strength of current drive capability (25%, 50%, 75%
|
||||
* or 100%) @ref pcal6408a_pin_drive_strength_t
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
ret_code_t pcal6408a_pin_cfg_drive_strength(uint32_t pin_number,
|
||||
pcal6408a_pin_drive_strength_t drive_strength_config);
|
||||
|
||||
/**
|
||||
* @brief Function for setting polarity inversion of a given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an input.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] polarity_mask Specifies the mask.
|
||||
* @param[in] flag Operation, whether mask should be written into register,
|
||||
* values should be cleared or set @ref pcal6408a_port_op_t
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_polarity_inversion(uint32_t port_number,
|
||||
uint8_t polarity_mask,
|
||||
pcal6408a_port_op_t flag);
|
||||
|
||||
/**
|
||||
* @brief Function for setting interrupt of a given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an input.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] interrupt_mask Specifies the mask.
|
||||
* @param[in] flag Operation, whether mask should be written into register,
|
||||
* values should be cleared or set @ref pcal6408a_port_op_t
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_interrupt(uint32_t port_number,
|
||||
uint8_t interrupt_mask,
|
||||
pcal6408a_port_op_t flag);
|
||||
|
||||
/**
|
||||
* @brief Function for setting input latch of a given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an input.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] latch_mask Specifies the mask.
|
||||
* @param[in] flag Operation, whether mask should be written into register,
|
||||
* values should be cleared or set @ref pcal6408a_port_op_t
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_latch(uint32_t port_number,
|
||||
uint8_t latch_mask,
|
||||
pcal6408a_port_op_t flag);
|
||||
|
||||
/**
|
||||
* @brief Function for setting drive strength for a given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an output.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] drive_strength_mask Specifies the mask. Note that for each pin there are dedicated
|
||||
* two adjacent bits.
|
||||
* @param[in] flag Operation, whether mask should be written into register,
|
||||
* values should be cleared or set @ref pcal6408a_port_op_t
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
ret_code_t pcal6408a_port_cfg_drive_strength(uint32_t port_number,
|
||||
uint16_t drive_strength_mask,
|
||||
pcal6408a_port_op_t flag);
|
||||
|
||||
/**
|
||||
* @brief Function for selecting push-pull or open-drain I/O stage for the given port.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] io_stage_config I/O stage of the port (push-pull or open-drain)
|
||||
* @ref pcal6408a_port_io_stage_t
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_io_stage(uint32_t port_number,
|
||||
pcal6408a_port_io_stage_t io_stage_config);
|
||||
|
||||
/**
|
||||
* @brief Function for configuring the given pin number as output.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
*
|
||||
* @return Error code from pin config set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_output(uint32_t pin_number);
|
||||
|
||||
/**
|
||||
* @brief Function for configuring the given pin number as input.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] pull_config State of the pin pull resistor (no pull, pulled down, or pulled high)
|
||||
* @ref pcal6408a_pin_pull_t
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
ret_code_t pcal6408a_pin_cfg_input(uint32_t pin_number, pcal6408a_pin_pull_t pull_config);
|
||||
|
||||
/**
|
||||
* @brief Function for setting a pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an output for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number to set.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_set(uint32_t pin_number);
|
||||
|
||||
/**
|
||||
* @brief Function for clearing a pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an output for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number to clear.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_clear(uint32_t pin_number);
|
||||
|
||||
/**
|
||||
* @brief Function for configuring the pin range as outputs.
|
||||
*
|
||||
* @note For configuring only one pin as an output use @ref pcal6408a_pin_cfg_output.
|
||||
*
|
||||
* @param[in] pin_range_start Specifies the start number (inclusive) in the range of pin numbers
|
||||
* to be configured.
|
||||
* @param[in] pin_range_end Specifies the end number (inclusive) in the range of pin numbers
|
||||
* to be configured.
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_LENGTH If start number is greater than end number.
|
||||
* @retval other Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
ret_code_t pcal6408a_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end);
|
||||
|
||||
/**
|
||||
* @brief Function for configuring the pin range as inputs.
|
||||
*
|
||||
* @note For configuring only one pin as an input use @ref pcal6408a_pin_cfg_input.
|
||||
*
|
||||
* @param[in] pin_range_start Specifies the start number (inclusive) in the range of pin numbers
|
||||
* to be configured.
|
||||
* @param[in] pin_range_end Specifies the end number (inclusive) in the range of pin numbers
|
||||
* to be configured.
|
||||
* @param[in] pull_config State of the pin pull resistor (no pull, pulled down, or pulled high)
|
||||
* @ref pcal6408a_pin_pull_t
|
||||
*
|
||||
* @retval NRF_ERROR_INVALID_LENGTH If start number is greater than end number.
|
||||
* @retval other Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
ret_code_t pcal6408a_range_cfg_input(uint32_t pin_range_start,
|
||||
uint32_t pin_range_end,
|
||||
pcal6408a_pin_pull_t pull_config);
|
||||
|
||||
/**
|
||||
* @brief Function for setting the direction for a given pin.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] direction Specifies the direction.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_dir_set(uint32_t pin_number,
|
||||
pcal6408a_pin_dir_t direction);
|
||||
|
||||
/**
|
||||
* @brief Function for toggling a given pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an output for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_toggle(uint32_t pin_number);
|
||||
|
||||
/**
|
||||
* @brief Function for writing a value to a given pin.
|
||||
*
|
||||
* @note Note that the pin must be configured as an output for this function to have any effect.
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
* @param[in] value Specifies the value to be written to the pin.
|
||||
* @arg 0 Clears the pin.
|
||||
* @arg 1 Sets the pin.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_write(uint32_t pin_number, uint8_t value);
|
||||
|
||||
/**
|
||||
* @brief Function for reading the input level of a given pin.
|
||||
*
|
||||
* @note Input data should be updated prior using this function, with @ref pcal6408a_pin_data_update
|
||||
*
|
||||
* @param[in] pin_number Specifies the pin number.
|
||||
*
|
||||
* @return Error code from pin_cfg_reg_set @ref pcal6408a_pin_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE uint32_t pcal6408a_pin_read(uint32_t pin_number);
|
||||
|
||||
/**
|
||||
* @brief Function for setting the direction of a port.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] direction Specifies the direction.
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_dir_set(uint32_t port_number,
|
||||
pcal6408a_port_dir_t direction);
|
||||
|
||||
/**
|
||||
* @brief Function for reading a given port.
|
||||
*
|
||||
* @note Input data should be updated prior using this function, with @ref pcal6408a_pin_data_update
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE uint32_t pcal6408a_port_read(uint32_t port_number);
|
||||
|
||||
/**
|
||||
* @brief Function for writing to a given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an output.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] value Specifies the value to be written to the port.
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_write(uint32_t port_number, uint8_t value);
|
||||
|
||||
/**
|
||||
* @brief Function for setting individual pins on given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an output.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] set_mask Mask specifying which pins to set. A bit set to 1 indicates that
|
||||
* the corresponding port pin shall be set.
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_set(uint32_t port_number, uint8_t set_mask);
|
||||
|
||||
/**
|
||||
* @brief Function for clearing individual pins on given port.
|
||||
*
|
||||
* @note Note that this function have an effect only for pins that are configured as an output.
|
||||
*
|
||||
* @param[in] port_number Specifies the port number.
|
||||
* @param[in] clr_mask Mask specifying which pins to clear. A bit set to 1 indicates that
|
||||
* the corresponding port pin shall be cleared.
|
||||
*
|
||||
* @return Error code from port_cfg_reg_set @ref pcal6408a_port_cfg_reg_set
|
||||
*/
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_clear(uint32_t port_number, uint8_t clr_mask);
|
||||
|
||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_polarity_inversion(uint32_t pin_number, bool state)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_POLARITY_INVERSION, pin_number, state);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_interrupt(uint32_t pin_number, bool state)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_INTERRUPT_MASK, pin_number, state);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_latch(uint32_t pin_number, bool state)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_INPUT_LATCH, pin_number, state);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_polarity_inversion(uint32_t port_number,
|
||||
uint8_t polarity_mask,
|
||||
pcal6408a_port_op_t flag)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_POLARITY_INVERSION,
|
||||
port_number,
|
||||
polarity_mask,
|
||||
flag);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_interrupt(uint32_t port_number,
|
||||
uint8_t interrupt_mask,
|
||||
pcal6408a_port_op_t flag)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_INTERRUPT_MASK,
|
||||
port_number,
|
||||
interrupt_mask,
|
||||
flag);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_latch(uint32_t port_number,
|
||||
uint8_t latch_mask,
|
||||
pcal6408a_port_op_t flag)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_INPUT_LATCH,
|
||||
port_number,
|
||||
latch_mask,
|
||||
flag);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_cfg_io_stage(uint32_t port_number,
|
||||
pcal6408a_port_io_stage_t io_stage_config)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT_CONFIGURATION,
|
||||
port_number * PCAL6408A_INNER_PIN_COUNT,
|
||||
io_stage_config);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_cfg_output(uint32_t pin_number)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
pin_number,
|
||||
PCAL6408A_PIN_DIR_OUTPUT);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_set(uint32_t pin_number)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT, pin_number, PCAL6408A_PIN_SET);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_clear(uint32_t pin_number)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT, pin_number, PCAL6408A_PIN_CLR);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_dir_set(uint32_t pin_number, pcal6408a_pin_dir_t direction)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_CONFIGURATION, pin_number, direction);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_toggle(uint32_t pin_number)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(
|
||||
PCAL6408A_REG_OUTPUT_PORT,
|
||||
pin_number,
|
||||
!pcal6408a_pin_cfg_reg_get(PCAL6408A_REG_OUTPUT_PORT, pin_number));
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_pin_write(uint32_t pin_number, uint8_t value)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT, pin_number, value);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t pcal6408a_pin_read(uint32_t pin_number)
|
||||
{
|
||||
return pcal6408a_pin_cfg_reg_get(PCAL6408A_REG_INPUT_PORT, pin_number);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_dir_set(uint32_t port_number,
|
||||
pcal6408a_port_dir_t direction)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_CONFIGURATION,
|
||||
port_number,
|
||||
direction,
|
||||
PCAL6408A_PORT_WRITE);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t pcal6408a_port_read(uint32_t port_number)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_get(PCAL6408A_REG_INPUT_PORT, port_number);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_write(uint32_t port_number, uint8_t value)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT,
|
||||
port_number,
|
||||
value,
|
||||
PCAL6408A_PORT_WRITE);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_set(uint32_t port_number, uint8_t set_mask)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT,
|
||||
port_number,
|
||||
set_mask,
|
||||
PCAL6408A_PORT_SET);
|
||||
}
|
||||
|
||||
__STATIC_INLINE ret_code_t pcal6408a_port_clear(uint32_t port_number, uint8_t clr_mask)
|
||||
{
|
||||
return pcal6408a_port_cfg_reg_set(PCAL6408A_REG_OUTPUT_PORT,
|
||||
port_number,
|
||||
clr_mask,
|
||||
PCAL6408A_PORT_CLEAR);
|
||||
}
|
||||
|
||||
#endif //SUPPRESS_INLINE_IMPLEMENTATION
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PCAL6408A_H__
|
||||
59
components/drivers_ext/pcal6408a/pcal6408a_internal.h
Normal file
59
components/drivers_ext/pcal6408a/pcal6408a_internal.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef PCAL6408A_INTERNAL_H__
|
||||
#define PCAL6408A_INTERNAL_H__
|
||||
|
||||
#define PCAL6408A_REG_COUNT_SEQUENCE_1 4
|
||||
#define PCAL6408A_REG_COUNT_SEQUENCE_2 7
|
||||
#define PCAL6408A_REG_COUNT_ALL 12
|
||||
|
||||
#define PCAL6408A_INNER_PIN_COUNT 8
|
||||
#define PCAL6408A_DRIVE_STRENGTH_REG_0_PIN_MAX 3
|
||||
|
||||
/**
|
||||
* @brief Structure containing expander instance.
|
||||
*/
|
||||
typedef struct {
|
||||
nrf_twi_sensor_t * p_sensor_data;
|
||||
uint8_t sensor_addr;
|
||||
uint8_t registers[PCAL6408A_REG_COUNT_ALL];
|
||||
} pcal6408a_instance_t;
|
||||
|
||||
#endif // PCAL6408A_INTERNAL_H__
|
||||
474
components/drivers_ext/st7735/st7735.c
Normal file
474
components/drivers_ext/st7735/st7735.c
Normal file
@@ -0,0 +1,474 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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)
|
||||
1002
components/drivers_ext/sx1509b/sx1509b.c
Normal file
1002
components/drivers_ext/sx1509b/sx1509b.c
Normal file
File diff suppressed because it is too large
Load Diff
1238
components/drivers_ext/sx1509b/sx1509b.h
Normal file
1238
components/drivers_ext/sx1509b/sx1509b.h
Normal file
File diff suppressed because it is too large
Load Diff
232
components/drivers_ext/sx1509b/sx1509b_internal.h
Normal file
232
components/drivers_ext/sx1509b/sx1509b_internal.h
Normal file
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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
|
||||
142
components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c
Normal file
142
components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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" */
|
||||
164
components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h
Normal file
164
components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2009 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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__ */
|
||||
124
components/drivers_ext/uda1380/uda1380.c
Normal file
124
components/drivers_ext/uda1380/uda1380.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (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;
|
||||
}
|
||||
140
components/drivers_ext/uda1380/uda1380.h
Normal file
140
components/drivers_ext/uda1380/uda1380.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING 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__ */
|
||||
Reference in New Issue
Block a user