mirror of
https://github.com/eclipse/upm.git
synced 2025-03-26 02:10:02 +03:00

* Main C implementation * C++ wrapper on C implementation Signed-off-by: Assam Boudjelthia <assam.boudjelthia@fi.rohmeurope.com>
703 lines
19 KiB
C
Executable File
703 lines
19 KiB
C
Executable File
/*
|
|
* The MIT License (MIT)
|
|
*
|
|
* Author: Assam Boudjelthia
|
|
* Copyright (c) 2018 Rohm Semiconductor.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "bh1749.h"
|
|
|
|
#define DEFAULT_OP_MODE INT_JUDGE_1
|
|
#define DEFAULT_MEAS_TIME MEAS_240MS
|
|
#define DEFAULT_RGB_GAIN RGB_GAIN_1X
|
|
#define DEFAULT_IR_GAIN IR_GAIN_1X
|
|
#define DEFAULT_INT_SOURCE RED
|
|
#define DEFUALT_THRESHOLD_HIGH 511
|
|
|
|
/**
|
|
* @brief Reads the value of a register
|
|
*
|
|
* @param dev The sensor context
|
|
* @param reg Register address
|
|
* @param data Pointer of uint8_t to save register value
|
|
* @return UPM result
|
|
*/
|
|
static upm_result_t bh1749_read_register(bh1749_context dev, uint8_t reg, uint8_t *data)
|
|
{
|
|
uint8_t value = mraa_i2c_read_byte_data(dev->i2c, reg);
|
|
if(value < 0) {
|
|
printf("%s: mraa_i2c_read_byte_data() failed\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
*data = value;
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Reads the values of a set of registers
|
|
*
|
|
* @param dev The sensor context
|
|
* @param reg Register address
|
|
* @param data Pointer of uint8_t to save registers values
|
|
* @return UPM result
|
|
*/
|
|
static upm_result_t bh1749_read_registers(bh1749_context dev, uint8_t reg, uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t value;
|
|
|
|
for(int i = 0; i < len; i++) {
|
|
if(bh1749_read_register(dev, reg + i, &value) != UPM_SUCCESS) {
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
*(data + i) = value;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Writes a value to a register
|
|
*
|
|
* @param dev The sensor context
|
|
* @param value Value to write
|
|
* @param reg Register address
|
|
* @return UPM result
|
|
*/
|
|
static upm_result_t bh1749_write_register(bh1749_context dev, uint8_t value, uint8_t reg)
|
|
{
|
|
if (mraa_i2c_write_byte_data(dev->i2c, value, reg) != MRAA_SUCCESS) {
|
|
printf("%s: mraa_i2c_write_byte_data() failed\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets a bit on in a register with a bit mask
|
|
*
|
|
* @param dev The sensor context
|
|
* @param reg Register address
|
|
* @param bit_mask Mask to use
|
|
* @return UPM result
|
|
*/
|
|
static upm_result_t bh1749_set_bit_on(bh1749_context dev, uint8_t reg, uint8_t bit_mask)
|
|
{
|
|
uint8_t reg_value;
|
|
int status;
|
|
|
|
status = bh1749_read_register(dev, reg, ®_value);
|
|
if(status < 0) {
|
|
printf("%s: Failed to read register 0x%2X\n", __FUNCTION__, reg);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
reg_value |= bit_mask;
|
|
return bh1749_write_register(dev, reg_value, reg);
|
|
}
|
|
|
|
/**
|
|
* @brief Sets a bit off in a register with a bit mask
|
|
*
|
|
* @param dev The sensor context
|
|
* @param reg Register address
|
|
* @param bit_mask Mask to use
|
|
* @return UPM result
|
|
*/
|
|
static upm_result_t bh1749_set_bit_off(bh1749_context dev, uint8_t reg, uint8_t bit_mask)
|
|
{
|
|
uint8_t reg_value;
|
|
int status;
|
|
|
|
status = bh1749_read_register(dev, reg, ®_value);
|
|
if(status < 0) {
|
|
printf("%s: Failed to read register 0x%2X\n", __FUNCTION__, reg);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
reg_value &= ~bit_mask;
|
|
return bh1749_write_register(dev, reg_value, reg);
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the value of a register as a given pattern with a bit mask
|
|
*
|
|
* @param dev The sensor context
|
|
* @param reg Register address
|
|
* @param value Value to write
|
|
* @param bit_mask Mask to use
|
|
* @return UPM result
|
|
*/
|
|
static upm_result_t bh1749_set_bits_with_mask(bh1749_context dev, uint8_t reg, uint8_t value, uint8_t bit_mask)
|
|
{
|
|
uint8_t reg_value;
|
|
int status;
|
|
|
|
status = bh1749_read_register(dev, reg, ®_value);
|
|
if(status < 0) {
|
|
printf("%s: Failed to read register 0x%2X\n", __FUNCTION__, reg);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
reg_value &= ~bit_mask;
|
|
reg_value |= value;
|
|
return bh1749_write_register(dev, reg_value, reg);
|
|
}
|
|
|
|
upm_result_t bh1749_check_who_am_i(bh1749_context dev)
|
|
{
|
|
uint8_t partId;
|
|
if(bh1749_read_register(dev, BH1749_SYSTEM_CONTROL, &partId) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
|
|
partId &= BH1749_SYSTEM_CONTROL_PART_MASK;
|
|
if(partId != BH1749_SYSTEM_CONTROL_PART_ID) {
|
|
printf("%s: wrong manufacturer ID\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
bh1749_context bh1749_init(int bus, int addr)
|
|
{
|
|
bh1749_context dev = (bh1749_context)malloc(sizeof(struct _bh1749_context));
|
|
if (!dev)
|
|
return NULL;
|
|
|
|
dev->i2c = NULL;
|
|
dev->interrupt = NULL;
|
|
|
|
if (mraa_init() != MRAA_SUCCESS) {
|
|
printf("%s: mraa_init() failed.\n", __FUNCTION__);
|
|
bh1749_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
if (!(dev->i2c = mraa_i2c_init(bus))) {
|
|
printf("%s: mraa_i2c_init() failed.\n", __FUNCTION__);
|
|
bh1749_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
if (mraa_i2c_address(dev->i2c, addr)) {
|
|
printf("%s: mraa_i2c_address() failed.\n", __FUNCTION__);
|
|
bh1749_close(dev);
|
|
return NULL;
|
|
}
|
|
|
|
if(bh1749_check_who_am_i(dev) != UPM_SUCCESS)
|
|
return NULL;
|
|
|
|
dev->enabled = false;
|
|
dev->isrEnabled = false;
|
|
if(bh1749_sensor_init(dev, DEFAULT_OP_MODE, DEFAULT_MEAS_TIME,
|
|
DEFAULT_RGB_GAIN, DEFAULT_IR_GAIN, DEFAULT_INT_SOURCE) != UPM_SUCCESS)
|
|
return NULL;
|
|
bh1749_set_threshold_high(dev, DEFUALT_THRESHOLD_HIGH);
|
|
|
|
return dev;
|
|
}
|
|
|
|
void bh1749_close(bh1749_context dev)
|
|
{
|
|
if(dev->isrEnabled)
|
|
bh1749_remove_isr(dev);
|
|
|
|
if (dev->i2c)
|
|
mraa_i2c_stop(dev->i2c);
|
|
|
|
free(dev);
|
|
}
|
|
|
|
upm_result_t bh1749_enable(bh1749_context dev)
|
|
{
|
|
int status;
|
|
|
|
status = bh1749_set_bit_on(dev, BH1749_MODE_CONTROL2,
|
|
BH1749_MODE_CONTROL2_RGB_MEASUREMENT_MASK);
|
|
if(status != UPM_SUCCESS) {
|
|
printf("%s: Failed to bh1749_enable RGB measurement\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->enabled = true;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_disable(bh1749_context dev)
|
|
{
|
|
int status;
|
|
|
|
status = bh1749_set_bit_off(dev, BH1749_MODE_CONTROL2,
|
|
BH1749_MODE_CONTROL2_RGB_MEASUREMENT_MASK);
|
|
if(status != UPM_SUCCESS) {
|
|
printf("%s: Failed to bh1749_disable RGB measurement\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->enabled = false;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_sensor_init(bh1749_context dev, OPERATING_MODES opMode,
|
|
MEAS_TIMES measTime,
|
|
RGB_GAINS rgbGain,
|
|
IR_GAINS irGain,
|
|
INT_SOURCES intSource)
|
|
{
|
|
if(bh1749_set_operating_mode(dev, opMode) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
if(bh1749_set_measurement_time(dev, measTime) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
if(bh1749_set_rgb_gain(dev, rgbGain) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
if(bh1749_set_ir_gain(dev, irGain) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
return bh1749_set_int_source(dev, intSource);
|
|
}
|
|
|
|
upm_result_t bh1749_set_operating_mode(bh1749_context dev, OPERATING_MODES opMode)
|
|
{
|
|
if(bh1749_write_register(dev, opMode, BH1749_PERSISTENCE) != UPM_SUCCESS) {
|
|
printf("%s: Setting operating mode failed\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->operating_mode = opMode;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_operating_mode(bh1749_context dev, uint8_t *opMode)
|
|
{
|
|
uint8_t value;
|
|
|
|
if(bh1749_read_register(dev, BH1749_PERSISTENCE, &value) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read operating mode\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
value &= BH1749_PERSISTENCE_MODE_MASK;
|
|
if(value != INT_JUDGE_0 && value != INT_JUDGE_1 &&
|
|
value != INT_JUDGE_4 && value != INT_JUDGE_4) {
|
|
printf("%s: Returned invalid mode\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
*opMode = value;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_set_measurement_time(bh1749_context dev, MEAS_TIMES measTime)
|
|
{
|
|
if(bh1749_set_bits_with_mask(dev, BH1749_MODE_CONTROL1, measTime,
|
|
BH1749_MODE_CONTROL1_ODR_MASK) != UPM_SUCCESS) {
|
|
printf("%s: Failed setting measurement time\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->meas_time = measTime;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_measurement_time(bh1749_context dev, uint8_t *meas_time)
|
|
{
|
|
uint8_t time_reg;
|
|
|
|
if(bh1749_read_register(dev, BH1749_MODE_CONTROL1, &time_reg) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read measurement time\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
time_reg &= BH1749_MODE_CONTROL1_ODR_MASK;
|
|
if(time_reg == MEAS_35MS)
|
|
*meas_time = 35;
|
|
else if(time_reg == MEAS_120MS)
|
|
*meas_time = 120;
|
|
else if(time_reg == MEAS_240MS)
|
|
*meas_time = 240;
|
|
else {
|
|
printf("%s: Returned invalid time\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_set_rgb_gain(bh1749_context dev, RGB_GAINS rgbGain)
|
|
{
|
|
if(bh1749_set_bits_with_mask(dev, BH1749_MODE_CONTROL1, rgbGain,
|
|
BH1749_MODE_CONTROL1_RGB_GAIN_MASK) != UPM_SUCCESS) {
|
|
printf("%s: Failed setting RGB gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->rgb_gain = rgbGain;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_rgb_gain(bh1749_context dev, uint8_t *gain)
|
|
{
|
|
uint8_t rgb_gain;
|
|
|
|
if(bh1749_read_register(dev, BH1749_MODE_CONTROL1, &rgb_gain) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read rgb gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
rgb_gain &= BH1749_MODE_CONTROL1_RGB_GAIN_MASK;
|
|
if(rgb_gain == RGB_GAIN_1X)
|
|
*gain = 1;
|
|
else if(rgb_gain == RGB_GAIN_32X)
|
|
*gain = 32;
|
|
else {
|
|
printf("%s: Returned invalid gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_set_ir_gain(bh1749_context dev, IR_GAINS irGain)
|
|
{
|
|
if(bh1749_set_bits_with_mask(dev, BH1749_MODE_CONTROL1, irGain,
|
|
BH1749_MODE_CONTROL1_IR_GAIN_MASK) != UPM_SUCCESS) {
|
|
printf("%s: Failed setting IR gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->ir_gain = irGain;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_ir_gain(bh1749_context dev, uint8_t *gain)
|
|
{
|
|
uint8_t ir_gain;
|
|
|
|
if(bh1749_read_register(dev, BH1749_MODE_CONTROL1, &ir_gain) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read rgb gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
ir_gain &= BH1749_MODE_CONTROL1_IR_GAIN_MASK;
|
|
if(ir_gain == IR_GAIN_1X)
|
|
*gain = 1;
|
|
else if(ir_gain == IR_GAIN_32X)
|
|
*gain = 32;
|
|
else {
|
|
printf("%s: Returned invalid gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_set_int_source(bh1749_context dev, INT_SOURCES intSource)
|
|
{
|
|
if(bh1749_set_bits_with_mask(dev, BH1749_INTERRUPT, intSource,
|
|
BH1749_INTERRUPT_SOURCE_MASK) != UPM_SUCCESS) {
|
|
printf("%s: Failed setting interrupt source gain\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->int_src = intSource;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
char bh1749_get_interrupt_source_char(bh1749_context dev)
|
|
{
|
|
char intSourceChar = ' ';
|
|
uint8_t intSource;
|
|
|
|
if(bh1749_read_register(dev, BH1749_INTERRUPT, &intSource) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read interrupt source\n", __FUNCTION__);
|
|
return intSourceChar;
|
|
}
|
|
|
|
intSource &= BH1749_INTERRUPT_SOURCE_MASK;
|
|
if(intSource == RED)
|
|
intSourceChar = 'r';
|
|
else if(intSource == GREEN)
|
|
intSourceChar = 'g';
|
|
else if(intSource == BLUE)
|
|
intSourceChar = 'b';
|
|
else {
|
|
printf("%s: Returned invalid interrupt source\n", __FUNCTION__);
|
|
return intSourceChar;
|
|
}
|
|
|
|
return intSourceChar;
|
|
}
|
|
|
|
upm_result_t bh1749_enable_interrupt(bh1749_context dev)
|
|
{
|
|
if(bh1749_set_bit_on(dev, BH1749_INTERRUPT, BH1749_INTERRUPT_EN_MASK) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
return bh1749_reset_interrupt(dev);
|
|
}
|
|
|
|
upm_result_t bh1749_disable_interrupt(bh1749_context dev)
|
|
{
|
|
return bh1749_set_bit_off(dev, BH1749_INTERRUPT, BH1749_INTERRUPT_EN_MASK);
|
|
}
|
|
|
|
upm_result_t bh1749_reset_interrupt(bh1749_context dev)
|
|
{
|
|
return bh1749_set_bit_on(dev, BH1749_SYSTEM_CONTROL, BH1749_SYSTEM_CONTROL_INT_RESET);
|
|
}
|
|
|
|
bool bh1749_is_interrupted(bh1749_context dev)
|
|
{
|
|
uint8_t intStatus;
|
|
|
|
if(bh1749_read_register(dev, BH1749_INTERRUPT, &intStatus) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read interrupt status\n", __FUNCTION__);
|
|
return false;
|
|
}
|
|
|
|
intStatus &= BH1749_INTERRUPT_STATUS_MASK;
|
|
if(intStatus != BH1749_INTERRUPT_STATUS_ACTIVE)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool bh1749_is_interrupt_enabled(bh1749_context dev)
|
|
{
|
|
uint8_t intStatus;
|
|
|
|
if(bh1749_read_register(dev, BH1749_INTERRUPT, &intStatus) != UPM_SUCCESS) {
|
|
printf("%s: Failed to read interrupt enabled\n", __FUNCTION__);
|
|
return false;
|
|
}
|
|
|
|
intStatus &= BH1749_INTERRUPT_EN_MASK;
|
|
if(intStatus != BH1749_INTERRUPT_EN_ENABLE)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
upm_result_t bh1749_soft_reset(bh1749_context dev)
|
|
{
|
|
return bh1749_set_bit_on(dev, BH1749_SYSTEM_CONTROL, BH1749_SYSTEM_CONTROL_SW_RESET_MASK);
|
|
}
|
|
|
|
upm_result_t bh1749_set_threshold_high(bh1749_context dev, uint16_t threshold)
|
|
{
|
|
if(bh1749_write_register(dev, threshold, BH1749_TH_LSBS) != UPM_SUCCESS ||
|
|
bh1749_write_register(dev, threshold >> 8, BH1749_TH_MSBS) != UPM_SUCCESS) {
|
|
printf("%s: Failed to write high threshold\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->int_thh = threshold;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_threshold_high(bh1749_context dev, uint16_t *threshold)
|
|
{
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_TH_MSBS, &data[0]) ||
|
|
bh1749_read_register(dev, BH1749_TH_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*threshold = data[0] << 8 | data[1];
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_set_threshold_low(bh1749_context dev, uint16_t threshold)
|
|
{
|
|
if(bh1749_write_register(dev, threshold, BH1749_TL_LSBS) != UPM_SUCCESS ||
|
|
bh1749_write_register(dev, threshold >> 8, BH1749_TL_MSBS) != UPM_SUCCESS) {
|
|
printf("%s: Failed to write low threshold\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
dev->int_thl = threshold;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_threshold_low(bh1749_context dev, uint16_t *threshold)
|
|
{
|
|
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_TL_MSBS, &data[0]) ||
|
|
bh1749_read_register(dev, BH1749_TL_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*threshold = data[0] << 8 | data[1];
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_red(bh1749_context dev, uint16_t *red)
|
|
{
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_RED_DATA_MSBS, &data[0]) != UPM_SUCCESS ||
|
|
bh1749_read_register(dev, BH1749_RED_DATA_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return -UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*red = data[0] << 8 | data[1];
|
|
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_green(bh1749_context dev, uint16_t *green)
|
|
{
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_GREEN_DATA_MSBS, &data[0]) != UPM_SUCCESS ||
|
|
bh1749_read_register(dev, BH1749_GREEN_DATA_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return -UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*green = data[0] << 8 | data[1];
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_blue(bh1749_context dev, uint16_t *blue)
|
|
{
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_BLUE_DATA_MSBS, &data[0]) != UPM_SUCCESS ||
|
|
bh1749_read_register(dev, BH1749_BLUE_DATA_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return -UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*blue = data[0] << 8 | data[1];
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_ir(bh1749_context dev, uint16_t *ir)
|
|
{
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_IR_DATA_MSBS, &data[0]) != UPM_SUCCESS ||
|
|
bh1749_read_register(dev, BH1749_IR_DATA_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return -UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*ir = data[0] << 8 | data[1];
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_green2(bh1749_context dev, uint16_t *green2)
|
|
{
|
|
uint8_t data[2];
|
|
|
|
if(bh1749_read_register(dev, BH1749_GREEN2_DATA_MSBS, &data[0]) != UPM_SUCCESS ||
|
|
bh1749_read_register(dev, BH1749_GREEN2_DATA_LSBS, &data[1]) != UPM_SUCCESS)
|
|
return -UPM_ERROR_OPERATION_FAILED;
|
|
|
|
*green2 = data[0] << 8 | data[1];
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_get_measurements(bh1749_context dev, uint16_t *result)
|
|
{
|
|
uint16_t value;
|
|
int step = 0;
|
|
|
|
if(bh1749_get_red(dev, &value) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
*(result + step++) = value;
|
|
if(bh1749_get_green(dev, &value) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
*(result + step++) = value;
|
|
if(bh1749_get_blue(dev, &value) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
*(result + step++) = value;
|
|
if(bh1749_get_ir(dev, &value) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
*(result + step++) = value;
|
|
if(bh1749_get_green2(dev, &value) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
*(result + step++) = value;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
upm_result_t bh1749_install_isr(bh1749_context dev, mraa_gpio_edge_t edge, int pin,
|
|
void (*isr)(void *), void *isr_args)
|
|
{
|
|
if(dev->isrEnabled)
|
|
bh1749_remove_isr(dev);
|
|
|
|
mraa_gpio_context isr_gpio = NULL;
|
|
|
|
if (!(isr_gpio = mraa_gpio_init(pin))) {
|
|
printf("%s: mraa_gpio_init() failed.\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
mraa_gpio_dir(isr_gpio, MRAA_GPIO_IN);
|
|
|
|
if (mraa_gpio_isr(isr_gpio, edge, isr, isr_args) != MRAA_SUCCESS) {
|
|
mraa_gpio_close(isr_gpio);
|
|
printf("%s: mraa_gpio_isr() failed.\n", __FUNCTION__);
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
}
|
|
|
|
dev->interrupt = isr_gpio;
|
|
dev->isrEnabled = true;
|
|
|
|
return UPM_SUCCESS;
|
|
}
|
|
|
|
void bh1749_remove_isr(bh1749_context dev)
|
|
{
|
|
mraa_gpio_isr_exit(dev->interrupt);
|
|
mraa_gpio_close(dev->interrupt);
|
|
dev->interrupt = NULL;
|
|
dev->isrEnabled = false;
|
|
}
|
|
|
|
upm_result_t bh1749_registers_dump(bh1749_context dev, char *dump)
|
|
{
|
|
uint8_t reg_values[10];
|
|
int count = 0;
|
|
int len = 3;
|
|
|
|
if(bh1749_read_registers(dev, BH1749_SYSTEM_CONTROL, reg_values, len) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
count += sprintf(dump, "0x40 ");
|
|
for(int i = 0; i < len; i++)
|
|
count += sprintf(dump + count, "%02X ", reg_values[i]);
|
|
sprintf(dump + count - 1, "\n");
|
|
|
|
len = 6;
|
|
if(bh1749_read_registers(dev, BH1749_INTERRUPT, reg_values, len) != UPM_SUCCESS)
|
|
return UPM_ERROR_OPERATION_FAILED;
|
|
count += sprintf(dump + count, "0x60 ");
|
|
for(int i = 0; i < len; i++)
|
|
count += sprintf(dump + count, "%02X ", reg_values[i]);
|
|
|
|
return UPM_SUCCESS;
|
|
}
|