/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * resarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <string.h>
#include <errno.h>
#include <assert.h>
#include <math.h>

#include "os/mynewt.h"
#include "hal/hal_i2c.h"
#include "hal/hal_spi.h"
#include "hal/hal_gpio.h"
#include "i2cn/i2cn.h"
#include "sensor/sensor.h"
#include "sensor/accel.h"
#include "adxl345/adxl345.h"
#include "adxl345_priv.h"
#include "modlog/modlog.h"
#include "stats/stats.h"
#include <syscfg/syscfg.h>

static struct hal_spi_settings spi_adxl345_settings = {
    .data_order = HAL_SPI_MSB_FIRST,
    .data_mode  = HAL_SPI_MODE3,
    .baudrate   = 4000,
    .word_size  = HAL_SPI_WORD_SIZE_8BIT,
};


/* Define the stats section and records */
STATS_SECT_START(adxl345_stat_section)
    STATS_SECT_ENTRY(read_errors)
    STATS_SECT_ENTRY(write_errors)
STATS_SECT_END

/* Define stat names for querying */
STATS_NAME_START(adxl345_stat_section)
    STATS_NAME(adxl345_stat_section, read_errors)
    STATS_NAME(adxl345_stat_section, write_errors)
STATS_NAME_END(adxl345_stat_section)

/* Global variable used to hold stats data */
STATS_SECT_DECL(adxl345_stat_section) g_adxl345stats;

#define ADXL345_LOG(lvl_, ...) \
    MODLOG_ ## lvl_(MYNEWT_VAL(ADXL345_LOG_MODULE), __VA_ARGS__)

#define ADXL345_NOTIFY_MASK  0x01
#define ADXL345_READ_MASK    0x02

#if MYNEWT_VAL(ADXL345_INT_ENABLE)
static void interrupt_handler(void * arg);
static int init_intpin(struct adxl345 * adxl345, hal_gpio_irq_handler_t handler,
                       void * arg);
static int enable_interrupt(struct sensor * sensor, uint8_t ints_to_enable);
static int disable_interrupt(struct sensor * sensor, uint8_t ints_to_disable);
#endif

/* Exports for the sensor API */
static int adxl345_sensor_read(struct sensor *, sensor_type_t,
                               sensor_data_func_t, void *, uint32_t);
static int adxl345_sensor_get_config(struct sensor *, sensor_type_t,
                                     struct sensor_cfg *);
static int adxl345_sensor_set_trigger_thresh(struct sensor * sensor,
                                             sensor_type_t sensor_type,
                                             struct sensor_type_traits * stt);
static int adxl345_sensor_set_notification(struct sensor * sensor,
                                           sensor_event_type_t sensor_event_type);
static int adxl345_sensor_unset_notification(struct sensor * sensor,
                                             sensor_event_type_t sensor_event_type);
static int adxl345_sensor_handle_interrupt(struct sensor * sensor);
static int adxl345_sensor_clear_low_thresh(struct sensor *sensor,
                                           sensor_type_t type);
static int adxl345_sensor_clear_high_thresh(struct sensor *sensor,
                                            sensor_type_t type);


static const struct sensor_driver adxl345_sensor_driver = {
     .sd_read                      = adxl345_sensor_read,
     .sd_get_config                = adxl345_sensor_get_config,
     .sd_set_trigger_thresh        = adxl345_sensor_set_trigger_thresh,
     .sd_set_notification          = adxl345_sensor_set_notification,
     .sd_unset_notification        = adxl345_sensor_unset_notification,
     .sd_handle_interrupt          = adxl345_sensor_handle_interrupt,
     .sd_clear_low_trigger_thresh  = adxl345_sensor_clear_low_thresh,
     .sd_clear_high_trigger_thresh = adxl345_sensor_clear_high_thresh
};

/**
 * Writes a single byte to the specified register using i2c
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_i2c_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
{
    int rc;
    uint8_t payload[2] = { reg, value };
    
    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 2,
        .buffer = payload
    };

    rc = i2cn_master_write(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1,
                           MYNEWT_VAL(ADXL345_I2C_RETRIES));

    if (rc) {
        ADXL345_LOG(ERROR,
                    "Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
                    itf->si_addr, reg, value);
        STATS_INC(g_adxl345stats, read_errors);
    }

    return rc;
}

/**
 * Reads a single byte from the specified register using i2c
 *
 * @param The sensor interface
 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_i2c_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
{
    int rc;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &reg
    };

    /* Register write */
    rc = i2cn_master_write(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1,
                           MYNEWT_VAL(ADXL345_I2C_RETRIES));
    if (rc) {
        ADXL345_LOG(ERROR, "I2C access failed at address 0x%02X\n",
                    itf->si_addr)
                    
        STATS_INC(g_adxl345stats, write_errors);
        return rc;
    }
    
    /* Read one byte back */
    data_struct.buffer = value;
    rc = i2cn_master_read(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1,
                          MYNEWT_VAL(ADXL345_I2C_RETRIES));

    if (rc) {
        ADXL345_LOG(ERROR, "Failed to read from 0x%02X:0x%02X - %02X\n",
                    itf->si_addr, reg, rc);
        STATS_INC(g_adxl345stats, read_errors);
    }
    return rc;
}

/**
 * Read multiple bytes starting from specified register over i2c
 *    
 * @param The sensor interface
 * @param The register address start reading from
 * @param Pointer to where the register value should be written
 * @param Number of bytes to read
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_i2c_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer, uint8_t len)
{
    int rc;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &reg
    };

    /* Register write */
    rc = i2cn_master_write(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1,
                           MYNEWT_VAL(ADXL345_I2C_RETRIES));
    if (rc) {
        ADXL345_LOG(ERROR, "I2C access failed at address 0x%02X\n",
                    itf->si_addr);
        STATS_INC(g_adxl345stats, write_errors);
        return rc;
    }

    /* Read data */
    data_struct.len = len;
    data_struct.buffer = buffer;
    rc = i2cn_master_read(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1,
                          MYNEWT_VAL(ADXL345_I2C_RETRIES));

    if (rc) {
        ADXL345_LOG(ERROR, "Failed to read from 0x%02X:0x%02X\n",
                    itf->si_addr, reg);
        STATS_INC(g_adxl345stats, read_errors);
    }

    return rc;
}

/**
 * Writes a single byte to the specified register using SPI
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_spi_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
{
    int rc;

    /* Select the device */
    hal_gpio_write(itf->si_cs_pin, 0);

    /* Send the address */
    rc = hal_spi_tx_val(itf->si_num, reg & ~ADXL345_SPI_READ_CMD_BIT);
    if (rc == 0xFFFF) {
        rc = SYS_EINVAL;
        ADXL345_LOG(ERROR, "SPI_%u register write failed addr:0x%02X\n",
                    itf->si_num, reg);
        STATS_INC(g_adxl345stats, write_errors);
        goto err;
    }

    /* Read data */
    rc = hal_spi_tx_val(itf->si_num, value);
    if (rc == 0xFFFF) {
        rc = SYS_EINVAL;
        ADXL345_LOG(ERROR, "SPI_%u write failed addr:0x%02X\n",
                    itf->si_num, reg);
        STATS_INC(g_adxl345stats, write_errors);
        goto err;
    }

    rc = 0;

err:
    /* De-select the device */
    hal_gpio_write(itf->si_cs_pin, 1);

    return rc;
}


/**
 * Reads a single byte from the specified register using SPI
 *

 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_spi_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
{
    uint16_t retval;
    int rc = 0;

    /* Select the device */
    hal_gpio_write(itf->si_cs_pin, 0);

    /* Send the address */
    retval = hal_spi_tx_val(itf->si_num, reg | ADXL345_SPI_READ_CMD_BIT);
    
    if (retval == 0xFFFF) {
        rc = SYS_EINVAL;
        ADXL345_LOG(ERROR, "SPI_%u register write failed addr:0x%02X\n",
                    itf->si_num, reg);
        STATS_INC(g_adxl345stats, read_errors);
        goto err;
    }

    /* Read data */
    retval = hal_spi_tx_val(itf->si_num, 0);
    if (retval == 0xFFFF) {
        rc = SYS_EINVAL;
        ADXL345_LOG(ERROR, "SPI_%u read failed addr:0x%02X\n",
                     itf->si_num, reg);
        STATS_INC(g_adxl345stats, read_errors);
        goto err;
    }
    *value = retval;
    
err:
    /* De-select the device */
    hal_gpio_write(itf->si_cs_pin, 1);

    return rc;
}

/**
 * Read multiple bytes starting from specified register over SPI
 *
 * @param The sensor interface
 * @param The register address start reading from
 * @param Pointer to where the register value should be written
 * @param Number of bytes to read
 *
 * @return 0 on success, non-zero on failure
 */
int
adxl345_spi_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer,
                    uint8_t len)
{
    int i;
    uint16_t retval;
    int rc = 0;

    /* Select the device */
    hal_gpio_write(itf->si_cs_pin, 0);

    /* Send the address */
    retval = hal_spi_tx_val(itf->si_num, reg | ADXL345_SPI_READ_CMD_BIT
                            | ADXL345_SPI_MULTIBYTE_CMD_BIT);
    
    if (retval == 0xFFFF) {
        rc = SYS_EINVAL;
        ADXL345_LOG(ERROR, "SPI_%u register write failed addr:0x%02X\n",
                    itf->si_num, reg);
        STATS_INC(g_adxl345stats, read_errors);
        goto err;
    }

    for (i = 0; i < len; i++) {
        /* Read data */
        retval = hal_spi_tx_val(itf->si_num, 0);
        if (retval == 0xFFFF) {
            rc = SYS_EINVAL;
            ADXL345_LOG(ERROR, "SPI_%u read failed addr:0x%02X\n",
                        itf->si_num, reg);
            STATS_INC(g_adxl345stats, read_errors);
            goto err;
        }
        buffer[i] = retval;
    }

err:
    /* De-select the device */
    hal_gpio_write(itf->si_cs_pin, 1);

    return rc;
}


/**
 * Write byte to ADXL345 sensor over different interfaces
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero on failure
 */
int
adxl345_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
{
    int rc;

    rc = sensor_itf_lock(itf, MYNEWT_VAL(ADXL345_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    if (itf->si_type == SENSOR_ITF_I2C) {
        rc = adxl345_i2c_write8(itf, reg, value);
    } else {
        rc = adxl345_spi_write8(itf, reg, value);
    }

    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Read byte data from ADXL345 sensor over different interfaces
 *
 * @param The sensor interface
 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero on failure
 */
int
adxl345_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
{
    int rc;

    rc = sensor_itf_lock(itf, MYNEWT_VAL(ADXL345_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    if (itf->si_type == SENSOR_ITF_I2C) {
        rc = adxl345_i2c_read8(itf, reg, value);
    } else {
        rc = adxl345_spi_read8(itf, reg, value);
    }

    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Read multiple bytes starting from specified register over different interfaces
 *
 * @param The sensor interface
 * @param The register address start reading from
 * @param Pointer to where the register value should be written
 * @param Number of bytes to read
 *
 * @return 0 on success, non-zero on failure
 */
int
adxl345_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer,
                uint8_t len)
{
    int rc;

    rc = sensor_itf_lock(itf, MYNEWT_VAL(ADXL345_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    if (itf->si_type == SENSOR_ITF_I2C) {
        rc = adxl345_i2c_readlen(itf, reg, buffer, len);
    } else {
        rc = adxl345_spi_readlen(itf, reg, buffer, len);
    }

    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Sets ADXL345 into new power mode
 *
 * @param The sensor interface
 * @param Power mode to set
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_power_mode(struct sensor_itf *itf, enum adxl345_power_mode state)
{
    uint8_t reg;
    int rc;
  
    rc = adxl345_read8(itf, ADXL345_POWER_CTL, &reg);
    if (rc) {
        return rc;
    }

    reg &= 0xF3;
    reg |= ((uint8_t)state) << 2;
  
    return adxl345_write8(itf, ADXL345_POWER_CTL, (uint8_t)reg);
}

/**
 * Gets power mode ADXL345 is currently in
 *
 * @param The sensor interface
 * @param Pointer to store current power mode
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_power_mode(struct sensor_itf *itf, enum adxl345_power_mode *state)
{
    uint8_t reg;
    int rc;

    rc = adxl345_read8(itf, ADXL345_POWER_CTL, &reg);
    if (rc) {
        return rc;
    }

    reg &= 0xC;
    reg >>= 2;

    *state = (enum adxl345_accel_range)reg;

    return 0;
}

/**
 * Sets whether low power mode is enabled. Low power mode acheives lower
 * power consumption at the expense of higher noise, but is only effective
 * at sample rates between 12.5Hz and 400Hz
 *
 * @param The sensor interface
 * @param Setting to use for low power mode
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_low_power_enable(struct sensor_itf *itf, uint8_t enable)
{
    uint8_t reg;
    int rc;
  
    rc = adxl345_read8(itf, ADXL345_BW_RATE, &reg);
    if (rc) {
        return rc;
    }

    reg &= 0x0F;
    if (enable) {
        reg |= 0x10;
    }
  
    return adxl345_write8(itf, ADXL345_BW_RATE, (uint8_t)reg);
}

/**
 * Gets current setting of low power mode. Low power mode acheives lower
 * power consumption at the expense of higher noise, but is only effective
 * at sample rates between 12.5Hz and 400Hz
 *
 * @param The sensor interface
 * @param Pointer to store value
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_low_power_enable(struct sensor_itf *itf, uint8_t *enable)
{
    uint8_t reg;
    int rc;

    rc = adxl345_read8(itf, ADXL345_BW_RATE, &reg);
    if (rc) {
        return rc;
    }

    *enable = (reg & 0x10) != 0;

    return 0;
}

/**
 * Sets the accelerometer range to specified setting
 *
 * @param The sensor interface
 * @param accelerometer range to set
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_accel_range(struct sensor_itf *itf, enum adxl345_accel_range range)
{
    uint8_t reg;
    int rc;
  
    rc = adxl345_read8(itf, ADXL345_DATA_FORMAT, &reg);
    if (rc) {
        return rc;
    }

    reg &= 0xFC;
    reg |= (uint8_t)range;
  
    return adxl345_write8(itf, ADXL345_DATA_FORMAT, (uint8_t)reg);
}

/**
 * Gets the accelerometer range currently set
 *
 * @param The sensor interface
 * @param Pointer to location to store accelerometer range
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_accel_range(struct sensor_itf *itf, enum adxl345_accel_range *range)
{
    uint8_t reg;
    int rc;

    rc = adxl345_read8(itf, ADXL345_DATA_FORMAT, &reg);
    if (rc) {
        return rc;
    }

    *range = (enum adxl345_accel_range)(reg & 0x3);

    return 0;
}

/**
 * Sets new offsets in ADXL345
 *
 * @param The sensor interface
 * @param X offset
 * @param Y offset
 * @param Z offset
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_offsets(struct sensor_itf *itf, int8_t offset_x,
                    int8_t offset_y, int8_t offset_z)
{
    int rc;
  
    rc = adxl345_write8(itf, ADXL345_OFSX, offset_x);
    if (rc){
        return rc;
    }

    rc = adxl345_write8(itf, ADXL345_OFSY, offset_y);
    if (rc){
        return rc;
    }

    return adxl345_write8(itf, ADXL345_OFSZ, offset_z);
}

/**
 * Gets the offsets currently set
 *
 * @param The sensor interface
 * @param Pointer to location to store X offset
 * @param Pointer to location to store Y offset
 * @param Pointer to location to store Z offset
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_offsets(struct sensor_itf *itf, int8_t *offset_x,
                    int8_t *offset_y, int8_t *offset_z)
{

    int rc;
  
    rc = adxl345_read8(itf, ADXL345_OFSX, (uint8_t *)offset_x);
    if (rc){
        return rc;
    }

    rc = adxl345_read8(itf, ADXL345_OFSY, (uint8_t *)offset_y);
    if (rc){
        return rc;
    }

    return adxl345_read8(itf, ADXL345_OFSZ, (uint8_t *)offset_z);
}

/**
 * Sets new tap settings in ADXL345 sensor
 *
 * @param The sensor interface
 * @param Structure of new settings
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_tap_settings(struct sensor_itf *itf, struct adxl345_tap_settings settings)
{
    int rc;
    uint8_t enables = 0;
    
    rc = adxl345_write8(itf, ADXL345_THRESH_TAP, settings.threshold);
    if (rc) {
        return rc;
    }

    rc = adxl345_write8(itf, ADXL345_DUR, settings.duration);
    if (rc) {
        return rc;
    }

    rc = adxl345_write8(itf, ADXL345_LATENT, settings.latency);
    if (rc) {
        return rc;
    }

    rc = adxl345_write8(itf, ADXL345_WINDOW, settings.window);
    if (rc) {
        return rc;
    }

    enables |= settings.x_enable ? (1 << 2) : 0;
    enables |= settings.y_enable ? (1 << 1) : 0;
    enables |= settings.z_enable ? (1 << 0) : 0;
    enables |= settings.suppress ? (1 << 3) : 0;

    return adxl345_write8(itf, ADXL345_TAP_AXES, enables);
}

/**
 * Gets the current tap settings from ADXL345 sensor
 *
 * @param The sensor interface
 * @param Ponter to structure to store settings
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_tap_settings(struct sensor_itf *itf, struct adxl345_tap_settings *settings)
{
    int rc;
    uint8_t enables;
    
    rc = adxl345_read8(itf, ADXL345_THRESH_TAP, &(settings->threshold));
    if (rc) {
        return rc;
    }

    rc = adxl345_read8(itf, ADXL345_DUR, &(settings->duration));
    if (rc) {
        return rc;
    }

    rc = adxl345_read8(itf, ADXL345_LATENT, &(settings->latency));
    if (rc) {
        return rc;
    }

    rc = adxl345_read8(itf, ADXL345_WINDOW, &(settings->window));
    if (rc) {
        return rc;
    }

    rc = adxl345_read8(itf, ADXL345_TAP_AXES, &enables);
    if (rc) {
        return rc;
    }

    settings->x_enable = (enables & (1 << 2)) != 0;
    settings->x_enable = (enables & (1 << 1)) != 0;
    settings->x_enable = (enables & (1 << 0)) != 0;
    settings->suppress = (enables & (1 << 3)) != 0;

    return 0;
}

/**
 * Sets new threshold for triggering activity interrupt
 *
 * @param The sensor interface
 * @param threshold value (62.5mg/LSB)
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_active_threshold(struct sensor_itf *itf, uint8_t threshold)
{
    return adxl345_write8(itf, ADXL345_THRESH_ACT, threshold);
}

/**
 * Gets current threshold for triggering activity interrupt
 *
 * @param The sensor interface
 * @param Pointer to store threshold value (62.5mg/LSB)
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_active_threshold(struct sensor_itf *itf, uint8_t *threshold)
{
    return adxl345_read8(itf, ADXL345_THRESH_ACT, threshold);
}

/**
 * Sets new threshold and time for triggering inactivity interrupt
 *
 * @param The sensor interface
 * @param threshold value (62.5mg/LSB)
 * @param time value in seconds
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_inactive_settings(struct sensor_itf *itf, uint8_t threshold, uint8_t time)
{
    int rc;
  
    rc = adxl345_write8(itf, ADXL345_THRESH_INACT, threshold);
    if (rc){
        return rc;
    }

    return adxl345_write8(itf, ADXL345_TIME_INACT, time);
}

/**
 * Gets current threshold and time set for triggering inactivity interrupt
 *
 * @param The sensor interface
 * @param Pointer to store threshold value (62.5mg/LSB)
 * @param Ponter to store time value in seconds
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_inactive_settings(struct sensor_itf *itf, uint8_t *threshold, uint8_t *time)
{
    int rc;
  
    rc = adxl345_read8(itf, ADXL345_THRESH_INACT, threshold);
    if (rc){
        return rc;
    }

    return adxl345_read8(itf, ADXL345_TIME_INACT, time);
}

/**
 * Sets new activity/inactivity interrupt axis selections
 *
 * @param The sensor interface
 * @param Structure of new configuration
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_act_inact_enables(struct sensor_itf *itf, struct adxl345_act_inact_enables cfg)
{
    uint8_t reg = 0;

    reg |= cfg.inact_z     ? (1 << 0) : 0;
    reg |= cfg.inact_y     ? (1 << 1) : 0;
    reg |= cfg.inact_x     ? (1 << 2) : 0;
    reg |= cfg.inact_ac_dc ? (1 << 3) : 0;
    reg |= cfg.act_z       ? (1 << 4) : 0;
    reg |= cfg.act_y       ? (1 << 5) : 0;
    reg |= cfg.act_x       ? (1 << 6) : 0;
    reg |= cfg.act_ac_dc   ? (1 << 7) : 0;

    ADXL345_LOG(ERROR, "act_inact = 0x%x\n", reg);
    
    return adxl345_write8(itf, ADXL345_ACT_INACT_CTL, reg);
    
}

/**
 * Sets new activity/inactivity interrupt axis selections
 *
 * @param The sensor interface
 * @param Pointer to structure to store configuration
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_act_inact_enables(struct sensor_itf *itf, struct adxl345_act_inact_enables *cfg)
{
    int rc;
    uint8_t reg;

    rc = adxl345_read8(itf, ADXL345_ACT_INACT_CTL, &reg);
    if (rc) {
        return rc;
    }

    cfg->inact_z     = (reg & (1 << 0)) != 0;
    cfg->inact_y     = (reg & (1 << 1)) != 0;
    cfg->inact_x     = (reg & (1 << 2)) != 0;
    cfg->inact_ac_dc = (reg & (1 << 3)) != 0;
    cfg->act_z       = (reg & (1 << 4)) != 0;
    cfg->act_y       = (reg & (1 << 5)) != 0;
    cfg->act_x       = (reg & (1 << 6)) != 0;
    cfg->act_ac_dc   = (reg & (1 << 7)) != 0;

    return 0;
}

/**
 * Sets new threshold and time for triggering freefall interrupt
 *
 * @param The sensor interface
 * @param threshold value (62.5mg/LSB)
 * @param time value in seconds
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_freefall_settings(struct sensor_itf *itf, uint8_t threshold, uint8_t time)
{
    int rc;
  
    rc = adxl345_write8(itf, ADXL345_THRESH_FF, threshold);
    if (rc){
        return rc;
    }

    return adxl345_write8(itf, ADXL345_TIME_FF, time);
}

/**
 * Gets current threshold and time set for triggering freefall interrupt
 *
 * @param The sensor interface
 * @param Pointer to store threshold value (62.5mg/LSB)
 * @param Ponter to store time value in seconds
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_freefall_settings(struct sensor_itf *itf, uint8_t *threshold, uint8_t *time)
{
    int rc;
  
    rc = adxl345_read8(itf, ADXL345_THRESH_FF, threshold);
    if (rc){
        return rc;
    }

    return adxl345_read8(itf, ADXL345_TIME_FF, time);
}

/**
 * Sets new sample rate for measurements
 *
 * @param The sensor interface
 * @param sample rate value
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_set_sample_rate(struct sensor_itf *itf, enum adxl345_sample_rate rate)
{
    return adxl345_write8(itf, ADXL345_BW_RATE, (uint8_t) rate);
}

/**
 * Gets current sample rate settings
 *
 * @param The sensor interface
 * @param Pointer to store rate value
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_get_sample_rate(struct sensor_itf *itf, enum adxl345_sample_rate *rate)
{
    int rc;
    uint8_t reg;
  
    rc = adxl345_read8(itf, ADXL345_BW_RATE, &reg);
    if (rc){
        return rc;
    }

    *rate = (enum adxl345_sample_rate)(reg & 0xF);    
    return 0;
}

/**
 * Configures which interrupts are enabled and which interrupt pins they are 
 * mapped to.
 *
 * @param The sensor interface
 * @param which interrupts are enabled
 * @param which interrupts are mapped to which pin
 *
 * @return 0 on success, non-zero error on failure
 */
int
adxl345_setup_interrupts(struct sensor_itf *itf, uint8_t enables, uint8_t mapping)
{
    int rc;

    rc = adxl345_write8(itf, ADXL345_INT_MAP, mapping);
    if (rc) {
        return rc;
    }

    return adxl345_write8(itf, ADXL345_INT_ENABLE, enables);
}

/**
 * Clears interrupts (except DATA_READY, Watermark & Overrun which need data to
 * be read to clear). Provides status as output to identify which interrupts have
 * triggered.
 * 
 * @param The sensor interface
 * @param Pointer to store interrupt status
 *
 * @return 0 on success, non-zero error on failure 
 */
int adxl345_clear_interrupts(struct sensor_itf *itf, uint8_t *int_status)
{
    return adxl345_read8(itf, ADXL345_INT_SOURCE, int_status);
}

/**
 * Expects to be called back through os_dev_create().
 *
 * @param The device object associated with this accelerometer
 * @param Argument passed to OS device init, unused
 *
 * @return 0 on success, non-zero error on failure.
 */
int
adxl345_init(struct os_dev *dev, void *arg)
{
    struct adxl345 *adxl;
    struct sensor *sensor;
    int rc;

    if (!arg || !dev) {
        return SYS_ENODEV;
    }

    adxl = (struct adxl345 *) dev;

    adxl->cfg.mask = SENSOR_TYPE_ALL;

    sensor = &adxl->sensor;

    /* Initialise the stats entry */
    rc = stats_init(
        STATS_HDR(g_adxl345stats),
        STATS_SIZE_INIT_PARMS(g_adxl345stats, STATS_SIZE_32),
        STATS_NAME_INIT_PARMS(adxl345_stat_section));
    SYSINIT_PANIC_ASSERT(rc == 0);
    /* Register the entry with the stats registry */
    rc = stats_register(dev->od_name, STATS_HDR(g_adxl345stats));
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = sensor_init(sensor, dev);
    if (rc) {
        return rc;
    }

    /* Add the accelerometer/gyroscope driver */
    rc = sensor_set_driver(sensor, SENSOR_TYPE_ACCELEROMETER,
                           (struct sensor_driver *) &adxl345_sensor_driver);
    if (rc) {
        return rc;
    }

    rc = sensor_set_interface(sensor, arg);
    if (rc) {
        return rc;
    }

    rc = sensor_mgr_register(sensor);
    if (rc) {
        return rc;
    }

    if (sensor->s_itf.si_type == SENSOR_ITF_SPI) {
        rc = hal_spi_config(sensor->s_itf.si_num, &spi_adxl345_settings);
        if (rc == EINVAL) {
            return rc;
        }

        rc = hal_spi_enable(sensor->s_itf.si_num);
        if (rc) {
            return rc;
        }

        rc = hal_gpio_init_out(sensor->s_itf.si_cs_pin, 1);
        if (rc) {
            return rc;
        }
    }

#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    adxl->pdd.read_ctx.srec_sensor = sensor;
    adxl->pdd.notify_ctx.snec_sensor = sensor;

    rc = init_intpin(adxl, interrupt_handler, sensor);
    if (rc != 0) {
        return rc;
    }
#endif

    
    return 0;
}

/**
 * Configure ADXL345 sensor
 *
 * @param Sensor device ADXL345 structure
 * @param Sensor device ADXL345 config
 *
 * @return 0 on success, non-zero on failure
 */
int
adxl345_config(struct adxl345 *dev, struct adxl345_cfg *cfg)
{
    int rc;
    struct sensor_itf *itf;

    itf = SENSOR_GET_ITF(&(dev->sensor));

    /* Check device id is correct */
    uint8_t val = 0;
    rc = adxl345_read8(itf, ADXL345_DEVID, &val);
    if (rc) {
        return rc;
    }
    if (val != ADXL345_DEVID_VAL) {
        return SYS_EINVAL;
    }

    rc = adxl345_read8(itf, ADXL345_DATA_FORMAT, &val);
    if (rc) {
        return rc;
    }

    /* Set accelerometer into full resolution */
    val |= 0x08;

    /* Set interupt pin polarity to match local pin setting */
    if (dev->sensor.s_itf.si_ints[dev->pdd.int_num].active) {
        val &= ~0x20;
    } else {
        val |= 0x20;
    }

    rc = adxl345_write8(itf, ADXL345_DATA_FORMAT, val);
    if (rc) {
        return rc;
    } 
    
    /* Setup range as per config */
    rc = adxl345_set_accel_range(itf, cfg->accel_range);
    if (rc) {
        return rc;
    }
    dev->cfg.accel_range = cfg->accel_range;

    /* setup sample rate */
    rc = adxl345_set_sample_rate(itf, cfg->sample_rate);
    if (rc) {
        return rc;
    }
    dev->cfg.sample_rate = cfg->sample_rate;
        
    /* setup data offsets */
    rc = adxl345_set_offsets(itf, cfg->offset_x, cfg->offset_y, cfg->offset_z);
    if (rc) {
        return rc;
    }
    dev->cfg.offset_x = cfg->offset_x;
    dev->cfg.offset_y = cfg->offset_y;
    dev->cfg.offset_z = cfg->offset_z;

    /* setup tap detection settings */
    rc = adxl345_set_tap_settings(itf, cfg->tap_cfg);
    if (rc) {
        return rc;
    }
    dev->cfg.tap_cfg = cfg->tap_cfg;

    /* setup activity detection settings */
    rc = adxl345_set_active_threshold(itf, 0xFF);
    if (rc) {
        return rc;
    }
    
    rc = adxl345_set_inactive_settings(itf, 0, 0);
    if (rc) {
        return rc;
    }

    /* setup freefall settings */
    rc = adxl345_set_freefall_settings(itf, cfg->freefall_threshold, cfg->freefall_time);
    if (rc) {
        return rc;
    }
    dev->cfg.freefall_threshold = cfg->freefall_threshold;
    dev->cfg.freefall_time = cfg->freefall_time;

    /* setup low power mode */
    rc = adxl345_set_low_power_enable(itf, cfg->low_power_enable);
    if (rc) {
        return rc;
    }
    dev->cfg.low_power_enable = cfg->low_power_enable;
    
    /* setup default interrupt config */
    rc = adxl345_setup_interrupts(itf, 0, 0);
    if (rc) {
        return rc;
    }

    rc = adxl345_clear_interrupts(itf, &val);
    if (rc) {
        return rc;
    }
    
    /* Setup current power mode */
    rc = adxl345_set_power_mode(itf, cfg->power_mode);
    if (rc) {
        return rc;
    } 
    dev->cfg.power_mode = cfg->power_mode;

    
    rc = sensor_set_type_mask(&(dev->sensor), cfg->mask);
    if (rc) {
        return rc;
    }

    dev->cfg.mask = cfg->mask;

    return 0;
}

static float adxl345_convert_reg_to_ms2(int16_t val, float lsb_mg)
{
    float tmp = val * lsb_mg * 0.001; /* convert to g */
    return tmp * STANDARD_ACCEL_GRAVITY; /* convert to ms2 */
}

static uint8_t adxl345_convert_ms2_to_reg(float ms2, float lsb_mg)
{
    float tmp = (ms2 * 1000) / STANDARD_ACCEL_GRAVITY; /* convert to mg */
    tmp /= lsb_mg; /* convert to reg format */   
    return (uint8_t) tmp;
}

/**
 * Reads Accelerometer data from ADXL345 sensor
 *
 * @param Pointer to sensor interface
 * @param Pointer to structure to store result
 *
 * @return 0 on success, non-zero on failure
 */
int
adxl345_get_accel_data(struct sensor_itf *itf, struct sensor_accel_data *sad)
{
    int rc;

    uint8_t payload[6];
    int16_t x,y,z;

    float lsb_mg = 4; /* lsb is always 4mg when device is set to full resolution */

    /* Get a new accelerometer sample */
    rc = adxl345_readlen(itf, ADXL345_DATAX0, payload, 6);
    if (rc) {
        return rc;
    }

    x = (((int16_t)payload[1]) << 8) | payload[0];
    y = (((int16_t)payload[3]) << 8) | payload[2];
    z = (((int16_t)payload[5]) << 8) | payload[4];   

    /* calculate MS*2 values to provide to data_func */
    sad->sad_x = adxl345_convert_reg_to_ms2(x, lsb_mg);
    sad->sad_x_is_valid = 1;
    sad->sad_y = adxl345_convert_reg_to_ms2(y, lsb_mg);
    sad->sad_y_is_valid = 1;
    sad->sad_z = adxl345_convert_reg_to_ms2(z, lsb_mg);
    sad->sad_z_is_valid = 1;

    return 0;
}

/**
 * Read Accelerometer data from ADXL345 sensor
 *
 * @param Pointer to sensor structure
 * @param Type of sensor data to read
 * @param Pointer to function to call to output data
 * @param Pointer to data to pass to data_func
 * @param timeout value
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_read(struct sensor *sensor, sensor_type_t type,
                    sensor_data_func_t data_func, void *data_arg, uint32_t timeout)
{
    (void)timeout;
    int rc;

    struct sensor_itf *itf;
    struct sensor_accel_data sad;
  
    /* If the read isn't looking for accel don't do anything. */
    if (!(type & SENSOR_TYPE_ACCELEROMETER)) {
        return SYS_EINVAL;
    }
  
    itf = SENSOR_GET_ITF(sensor);
  
    rc = adxl345_get_accel_data(itf, &sad);
    if (rc) {
        return rc;
    }

    /* output data using data_func */
    rc = data_func(sensor, data_arg, &sad, SENSOR_TYPE_ACCELEROMETER);
    if (rc) {
        return rc;
    }
  
    return 0;
}

static int
adxl345_sensor_get_config(struct sensor *sensor, sensor_type_t type,
                          struct sensor_cfg *cfg)
{
    /* If the read isn't looking for accel, don't do anything. */
    if (!(type & SENSOR_TYPE_ACCELEROMETER)) {
        return SYS_EINVAL;
    }

    cfg->sc_valtype = SENSOR_VALUE_TYPE_FLOAT_TRIPLET;

    return 0;
}

#if MYNEWT_VAL(ADXL345_INT_ENABLE)
static void
interrupt_handler(void * arg)
{
    struct sensor *sensor = arg;
    sensor_mgr_put_interrupt_evt(sensor);
}

/**
 * Initialises the local interrupt pin 
 *
 * @param Pointer to device structure
 * @param interrupt handler to setup
 * @param Pointer to data to pass to irq
 *
 * @return 0 on success, non-zero on failure
 */
static int
init_intpin(struct adxl345 * adxl345, hal_gpio_irq_handler_t handler,
            void * arg)
{
    struct adxl345_private_driver_data *pdd = &adxl345->pdd;
    hal_gpio_irq_trig_t trig;
    int pin = -1;
    int rc;
    int i;

    for (i = 0; i < MYNEWT_VAL(SENSOR_MAX_INTERRUPTS_PINS); i++){
        pin = adxl345->sensor.s_itf.si_ints[i].host_pin;
        if (pin >= 0) {
            break;
        }
    }

    if (pin < 0) {
        ADXL345_LOG(ERROR, "Interrupt pin not configured\n");
        return SYS_EINVAL;
    }

    pdd->int_num = i;
    if (adxl345->sensor.s_itf.si_ints[pdd->int_num].active) {
        trig = HAL_GPIO_TRIG_RISING;
    } else {
        trig = HAL_GPIO_TRIG_FALLING;
    }
  
    if (adxl345->sensor.s_itf.si_ints[pdd->int_num].device_pin == 1) {
        pdd->int_route = 0x00;
    } else if (adxl345->sensor.s_itf.si_ints[pdd->int_num].device_pin == 2) {
        pdd->int_route = 0xFF;
    } else {
        ADXL345_LOG(ERROR, "Route not configured\n");
        return SYS_EINVAL;
    }

    rc = hal_gpio_irq_init(pin,
                           handler,
                           arg,
                           trig,
                           HAL_GPIO_PULL_NONE);
    if (rc != 0) {
        ADXL345_LOG(ERROR, "Failed to initialise interrupt pin %d\n", pin);
        return rc;
    } 
    
    return 0;
}

/**
 * Enables an interrupt in ADXL345 device
 *
 * @param Pointer to sensor structure
 * @param which interrupt(s) to enable
 *
 * @return 0 on success, non-zero on failure
 */
static int
enable_interrupt(struct sensor * sensor, uint8_t ints_to_enable)
{
    struct adxl345_private_driver_data *pdd;
    struct adxl345 *adxl345;
    struct sensor_itf *itf;

    if (ints_to_enable == 0) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &adxl345->pdd;
 
    /* if no interrupts are currently in use enable int pin */
    if (pdd->int_enable == 0) {
        hal_gpio_irq_enable(adxl345->sensor.s_itf.si_ints[pdd->int_num].host_pin);
    }
    
    /* update which interrupts are enabled */
    pdd->int_enable |= ints_to_enable;

    /* enable interrupt in device */
    return adxl345_setup_interrupts(itf, pdd->int_enable, pdd->int_route);
}

/**
 * Disables an interrupt in ADXL345 device
 *
 * @param Pointer to sensor structure
 * @param which interrupt(s) to disable
 *
 * @return 0 on success, non-zero on failure
 */
static int
disable_interrupt(struct sensor * sensor, uint8_t ints_to_disable)
{
    struct adxl345_private_driver_data *pdd;
    struct adxl345 *adxl345;
    struct sensor_itf *itf;

    if (ints_to_disable == 0) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &adxl345->pdd;
    
    /* update which interrupts are enabled */
    pdd->int_enable &= ~ints_to_disable;

    /* if no interrupts are now in use disable int pin */
    if (pdd->int_enable == 0) {
        hal_gpio_irq_disable(adxl345->sensor.s_itf.si_ints[pdd->int_num].host_pin);
    }

    /* update interrupt setup in device */
    return adxl345_setup_interrupts(itf, pdd->int_enable, pdd->int_route);
}
#endif

/**
 * Handles and interrupt, firing correct events
 *
 * @param Pointer to sensor structure
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_handle_interrupt(struct sensor * sensor)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    struct adxl345_private_driver_data *pdd;
    struct sensor_itf *itf;
    uint8_t int_status;
    
    int rc;

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);

    pdd = &adxl345->pdd;

    rc = adxl345_clear_interrupts(itf, &int_status);
    if (rc != 0) {
        ADXL345_LOG(ERROR, "Cound not read int status err=0x%02x\n", rc);
        return rc;
    }

    if (pdd->registered_mask & ADXL345_NOTIFY_MASK) {
        if (int_status & ADXL345_INT_SINGLE_TAP_BIT) {
            sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_SINGLE_TAP);
        }

        if (int_status & ADXL345_INT_DOUBLE_TAP_BIT) {
            sensor_mgr_put_notify_evt(&pdd->notify_ctx, SENSOR_EVENT_TYPE_DOUBLE_TAP);
        }
    }

    if ((pdd->registered_mask & ADXL345_READ_MASK) &&
        ((int_status & ADXL345_INT_ACTIVITY_BIT) ||
         (int_status & ADXL345_INT_INACTIVITY_BIT))) {
        ADXL345_LOG(ERROR, "READ EVT 0x%02x\n", int_status);
        sensor_mgr_put_read_evt(&pdd->read_ctx);
    }

    return 0;
#else
    return SYS_ENODEV;
#endif
}

/**
 * Sets up trigger thresholds and enables interrupts
 *
 * @param Pointer to sensor structure
 * @param type of sensor
 * @param threshold settings to configure
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_set_trigger_thresh(struct sensor * sensor,
                                  sensor_type_t sensor_type,
                                  struct sensor_type_traits * stt)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    struct sensor_itf *itf;
    int rc;
    const struct sensor_accel_data * low_thresh;
    const struct sensor_accel_data * high_thresh;
    uint8_t ints_to_enable = 0;
    float thresh;
    struct adxl345_private_driver_data *pdd;
    struct adxl345_act_inact_enables axis_enables = { 0 };

    if (sensor_type != SENSOR_TYPE_ACCELEROMETER) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    itf = SENSOR_GET_ITF(sensor);
    pdd = &adxl345->pdd;

    low_thresh  = stt->stt_low_thresh.sad;
    high_thresh = stt->stt_high_thresh.sad;

    if (low_thresh->sad_x_is_valid |
        low_thresh->sad_y_is_valid |
        low_thresh->sad_z_is_valid) {
        thresh = INFINITY;

        if (low_thresh->sad_x_is_valid) {
            axis_enables.inact_x = 1;
            if (thresh > low_thresh->sad_x) {
                thresh = low_thresh->sad_x;
            }
        }
        if (low_thresh->sad_y_is_valid) {
            axis_enables.inact_y = 1;
            if (thresh > low_thresh->sad_y) {
                thresh = low_thresh->sad_y;
            }
        }
        if (low_thresh->sad_z_is_valid) {
            axis_enables.inact_z = 1;
            if (thresh > low_thresh->sad_z) {
                thresh = low_thresh->sad_z;
            }
        }

        rc = adxl345_set_inactive_settings(itf,
                adxl345_convert_ms2_to_reg(thresh, 62.5), 2);
        
        if (rc) {
            return rc;
        }

        ints_to_enable |= ADXL345_INT_INACTIVITY_BIT;
    }

    if (high_thresh->sad_x_is_valid |
        high_thresh->sad_y_is_valid |
        high_thresh->sad_z_is_valid) {
        thresh = 0.0;

        if (high_thresh->sad_x_is_valid) {
            axis_enables.act_x = 1;
            if (thresh < high_thresh->sad_x) {
                thresh = high_thresh->sad_x;
            }
        }
        if (high_thresh->sad_y_is_valid) {
            axis_enables.act_y = 1;
            if (thresh < high_thresh->sad_y) {
                thresh = high_thresh->sad_y;
            }
        }
        if (high_thresh->sad_z_is_valid) {
            axis_enables.act_z = 1;
            if (thresh < high_thresh->sad_z) {
                thresh = high_thresh->sad_z;
            }
        }

        rc = adxl345_set_active_threshold(itf,
                   adxl345_convert_ms2_to_reg(thresh, 62.5));
        if (rc) {
            return rc;
        }

        ints_to_enable |= ADXL345_INT_ACTIVITY_BIT;
       
    }

    rc = enable_interrupt(sensor, ints_to_enable);
    if (rc) {
        return rc;
    }

    rc = adxl345_set_act_inact_enables(itf, axis_enables);
    if (rc) {
        return rc;
    }
    
    pdd->read_ctx.srec_type |= sensor_type;
    pdd->registered_mask |= ADXL345_READ_MASK;

    return 0;
#else
    return SYS_ENODEV;
#endif
}

/**
 * Disable the low threshold interrupt
 *
 * @param ptr to sensor
 * @param the Sensor type
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_clear_low_thresh(struct sensor *sensor,
                                 sensor_type_t type)
{
    struct adxl345 *adxl345;
    uint8_t ints_to_disable = ADXL345_INT_INACTIVITY_BIT;

    if (type != SENSOR_TYPE_ACCELEROMETER) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);

    /* if neither high or low threshs are now set disable read mask */
    if((adxl345->pdd.int_enable & ADXL345_INT_ACTIVITY_BIT) == 0) {
        adxl345->pdd.read_ctx.srec_type &= ~type;
        adxl345->pdd.registered_mask &= ~ADXL345_READ_MASK;
    }

    return disable_interrupt(sensor, ints_to_disable);
}


/**
 * Disable the high threshold interrupt
 *
 * @param ptr to sensor
 * @param the Sensor type
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_clear_high_thresh(struct sensor *sensor,
                                  sensor_type_t type)
{
    struct adxl345 *adxl345;
    uint8_t ints_to_disable = ADXL345_INT_ACTIVITY_BIT;

    if (type != SENSOR_TYPE_ACCELEROMETER) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);

    /* if neither high or low threshs are now set disable read mask */
    if((adxl345->pdd.int_enable & ADXL345_INT_INACTIVITY_BIT) == 0) {
        adxl345->pdd.read_ctx.srec_type &= ~type;
        adxl345->pdd.registered_mask &= ~ADXL345_READ_MASK;
    }

    return disable_interrupt(sensor, ints_to_disable);
}

/**
 * Enables notifications on tap or double tap events
 *
 * @param Pointer to sensor structure
 * @param which event to get notifications for
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_set_notification(struct sensor * sensor,
                                sensor_event_type_t sensor_event_type)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    uint8_t ints_to_enable = 0;
    struct adxl345_private_driver_data *pdd;
    int rc;

    ADXL345_LOG(ERROR, "Enabling notifications\n");
    
    if ((sensor_event_type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
                               SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
        return SYS_EINVAL;
    }

    /*XXX for now we do not support registering for both events */
    if (sensor_event_type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
                                        SENSOR_EVENT_TYPE_SINGLE_TAP)) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);
    pdd = &adxl345->pdd;

    if (pdd->registered_mask & ADXL345_NOTIFY_MASK) {
        return SYS_EBUSY;
    }

    /* Enable tap event*/
    if(sensor_event_type == SENSOR_EVENT_TYPE_DOUBLE_TAP) {
        ints_to_enable |= ADXL345_INT_DOUBLE_TAP_BIT;
    }
    if(sensor_event_type == SENSOR_EVENT_TYPE_SINGLE_TAP) {
        ints_to_enable |= ADXL345_INT_SINGLE_TAP_BIT;
    }

    rc = enable_interrupt(sensor, ints_to_enable);
    if (rc) {
        return rc;
    }

    pdd->notify_ctx.snec_evtype |= sensor_event_type;
    pdd->registered_mask |= ADXL345_NOTIFY_MASK;

    ADXL345_LOG(ERROR, "Enabled notifications\n");
    
    return 0;
#else
    return SYS_ENODEV;
#endif
}


/**
 * Disables notifications on tap or double tap events
 *
 * @param Pointer to sensor structure
 * @param which event to get notifications for
 *
 * @return 0 on success, non-zero on failure
 */
static int
adxl345_sensor_unset_notification(struct sensor * sensor,
                                  sensor_event_type_t sensor_event_type)
{
#if MYNEWT_VAL(ADXL345_INT_ENABLE)
    struct adxl345 * adxl345;
    uint8_t ints_to_disable = 0;

    if ((sensor_event_type & ~(SENSOR_EVENT_TYPE_DOUBLE_TAP |
                               SENSOR_EVENT_TYPE_SINGLE_TAP)) != 0) {
        return SYS_EINVAL;
    }

    /*XXX for now we do not support registering for both events */
    if (sensor_event_type == (SENSOR_EVENT_TYPE_DOUBLE_TAP |
                                        SENSOR_EVENT_TYPE_SINGLE_TAP)) {
        return SYS_EINVAL;
    }

    adxl345 = (struct adxl345 *)SENSOR_GET_DEVICE(sensor);

    adxl345->pdd.notify_ctx.snec_evtype &= ~sensor_event_type;
    adxl345->pdd.registered_mask &= ~ADXL345_NOTIFY_MASK;

    ints_to_disable |= ADXL345_INT_SINGLE_TAP_BIT;
    ints_to_disable |= ADXL345_INT_DOUBLE_TAP_BIT;
   
    return disable_interrupt(sensor, ints_to_disable);
    
#else
    return SYS_ENODEV;
#endif
}



