copy project from century 2in6 esl project

This commit is contained in:
muyuchl
2025-04-26 13:14:26 +08:00
commit 2c9b333b97
1507 changed files with 460409 additions and 0 deletions

View File

@@ -0,0 +1,359 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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" */

View File

@@ -0,0 +1,318 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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

View File

@@ -0,0 +1,476 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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);
}
}

View File

@@ -0,0 +1,120 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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

View File

@@ -0,0 +1,155 @@
/**
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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" */

View File

@@ -0,0 +1,114 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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

View File

@@ -0,0 +1,72 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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);
}

View File

@@ -0,0 +1,131 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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_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__ */

View File

@@ -0,0 +1,155 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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.
*/
static ret_code_t twi_init (void)
{
ret_code_t err_code;
const nrf_drv_twi_config_t twi_mcp4725_config = {
.scl = ARDUINO_SCL_PIN,
.sda = ARDUINO_SDA_PIN,
.frequency = NRF_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(void)
{
ret_code_t err_code = twi_init();
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" */

View File

@@ -0,0 +1,100 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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.
*/
/**
* @brief Function for setting up the driver.
*
* @return Values returned by @ref nrf_drv_twi_init.
*/
ret_code_t mcp4725_setup(void);
/**
* @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 nrf_drv_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

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdbool.h>
#include <stdint.h>
#include "twi_master.h"
#include "mpu6050.h"
/*lint ++flb "Enter library region" */
#define ADDRESS_WHO_AM_I (0x75U) // !< WHO_AM_I register identifies the device. Expected value is 0x68.
#define ADDRESS_SIGNAL_PATH_RESET (0x68U) // !<
static const uint8_t expected_who_am_i = 0x68U; // !< Expected value to get from WHO_AM_I register.
static uint8_t m_device_address; // !< Device address in bits [7:1]
bool mpu6050_init(uint8_t device_address)
{
bool transfer_succeeded = true;
m_device_address = (uint8_t)(device_address << 1);
// Do a reset on signal paths
uint8_t reset_value = 0x04U | 0x02U | 0x01U; // Resets gyro, accelerometer and temperature sensor signal paths.
transfer_succeeded &= mpu6050_register_write(ADDRESS_SIGNAL_PATH_RESET, reset_value);
// Read and verify product ID
transfer_succeeded &= mpu6050_verify_product_id();
return transfer_succeeded;
}
bool mpu6050_verify_product_id(void)
{
uint8_t who_am_i;
if (mpu6050_register_read(ADDRESS_WHO_AM_I, &who_am_i, 1))
{
if (who_am_i != expected_who_am_i)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
}
bool mpu6050_register_write(uint8_t register_address, uint8_t value)
{
uint8_t w2_data[2];
w2_data[0] = register_address;
w2_data[1] = value;
return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
}
bool mpu6050_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
{
bool transfer_succeeded;
transfer_succeeded = twi_master_transfer(m_device_address, &register_address, 1, TWI_DONT_ISSUE_STOP);
transfer_succeeded &= twi_master_transfer(m_device_address|TWI_READ_BIT, destination, number_of_bytes, TWI_ISSUE_STOP);
return transfer_succeeded;
}
/*lint --flb "Leave library region" */

View File

@@ -0,0 +1,111 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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 */

View File

@@ -0,0 +1,306 @@
/**
* Copyright (c) 2008 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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" */

View File

@@ -0,0 +1,155 @@
/**
* Copyright (c) 2012 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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_
/** @} */

View File

@@ -0,0 +1,143 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdbool.h>
#include <stdint.h>
#include "twi_master.h"
#include "synaptics_touchpad.h"
/*lint ++flb "Enter library region" */
#define PRODUCT_ID_BYTES 10U //!< Number of bytes to expect to be in product ID
static uint8_t m_device_address; // !< Device address in bits [7:1]
static const uint8_t expected_product_id[PRODUCT_ID_BYTES] = {'T', 'M', '1', '9', '4', '4', '-', '0', '0', '2'}; //!< Product ID expected to get from product ID query
bool touchpad_init(uint8_t device_address)
{
bool transfer_succeeded = true;
m_device_address = (uint8_t)(device_address << 1);
// Do a soft reset
uint8_t reset_command = 0x01;
transfer_succeeded &= touchpad_write_register(TOUCHPAD_RESET, reset_command);
// Page select 0
uint8_t page_to_select = 0x00;
transfer_succeeded &= touchpad_write_register(TOUCHPAD_PAGESELECT, page_to_select);
// Read and verify product ID
transfer_succeeded &= touchpad_product_id_verify();
return transfer_succeeded;
}
bool touchpad_product_id_verify(void)
{
bool transfer_succeeded = true;
uint8_t product_id[PRODUCT_ID_BYTES];
transfer_succeeded &= touchpad_product_id_read(product_id, PRODUCT_ID_BYTES);
for (uint8_t i = 0; i < 10; i++)
{
if (product_id[i] != expected_product_id[i])
{
transfer_succeeded = false;
}
}
return transfer_succeeded;
}
bool touchpad_reset(void)
{
uint8_t w2_data[2] = {TOUCHPAD_COMMAND, 0x01};
return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
}
bool touchpad_interrupt_status_read(uint8_t *interrupt_status)
{
return touchpad_read_register(TOUCHPAD_INT_STATUS, interrupt_status);
}
bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode)
{
return touchpad_write_register(TOUCHPAD_CONTROL, (uint8_t)mode);
}
bool touchpad_read_register(uint8_t register_address, uint8_t *value)
{
bool transfer_succeeded = true;
transfer_succeeded &= twi_master_transfer(m_device_address, &register_address, 1, TWI_DONT_ISSUE_STOP);
if (transfer_succeeded)
{
transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, value, 1, TWI_ISSUE_STOP);
}
return transfer_succeeded;
}
bool touchpad_write_register(uint8_t register_address, const uint8_t value)
{
uint8_t w2_data[2];
w2_data[0] = register_address;
w2_data[1] = value;
return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
}
bool touchpad_product_id_read(uint8_t * product_id, uint8_t product_id_bytes)
{
uint8_t w2_data[1];
bool transfer_succeeded = true;
w2_data[0] = TOUCHPAD_PRODUCT_ID;
transfer_succeeded &= twi_master_transfer(m_device_address, w2_data, 1, TWI_DONT_ISSUE_STOP);
if (transfer_succeeded)
{
transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, product_id, product_id_bytes, TWI_ISSUE_STOP);
}
return transfer_succeeded;
}
/*lint --flb "Leave library region" */

View File

@@ -0,0 +1,165 @@
/**
* Copyright (c) 2009 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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__ */

View File

@@ -0,0 +1,125 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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;
}

View File

@@ -0,0 +1,141 @@
/**
* Copyright (c) 2016 - 2017, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#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_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__ */