/*
 * 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
 * regarding 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 <assert.h>
#include "os/mynewt.h"
#include <hal/hal_bsp.h>
#include <adc/adc.h>
#include <mcu/cmsis_nvic.h>

/* Nordic headers */
#include <nrfx.h>
#include <nrfx_adc.h>

#include "adc_nrf51/adc_nrf51.h"

/**
 * Weak symbol, this is defined in Nordic drivers but not exported.
 * Needed for NVIC_SetVector().
 */
extern void ADC_IRQHandler(void);

#define NRF_ADC_CHANNEL_COUNT   (1)

struct nrf51_adc_stats {
    uint16_t adc_events;
    uint16_t adc_events_failed;
};
static struct nrf51_adc_stats nrf51_adc_stats;

static struct adc_dev *global_adc_dev;

static nrfx_adc_config_t *global_adc_config;
static struct nrf51_adc_dev_cfg *init_adc_config;

static struct adc_chan_config nrf51_adc_chans[NRF_ADC_CHANNEL_COUNT];
static nrfx_adc_channel_t *nrf_adc_chan;

static void
nrf51_adc_event_handler(const nrfx_adc_evt_t *event)
{
    nrfx_adc_done_evt_t *done_ev;
    int rc;

    if (global_adc_dev == NULL) {
        ++nrf51_adc_stats.adc_events_failed;
        return;
    }

    ++nrf51_adc_stats.adc_events;

    /* Right now only data reads supported, assert for unknown event
     * type.
     */
    assert(event->type == NRFX_ADC_EVT_DONE);

    done_ev = (nrfx_adc_done_evt_t * const) &event->data.done;

    rc = global_adc_dev->ad_event_handler_func(global_adc_dev,
            global_adc_dev->ad_event_handler_arg,
            ADC_EVENT_RESULT, done_ev->p_buffer,
            done_ev->size * sizeof(nrf_adc_value_t));
    if (rc != 0) {
        ++nrf51_adc_stats.adc_events_failed;
    }
}

/**
 * Open the NRF51 ADC device
 *
 * This function locks the device for access from other tasks.
 *
 * @param odev The OS device to open
 * @param wait The time in MS to wait.  If 0 specified, returns immediately
 *             if resource unavailable.  If OS_WAIT_FOREVER specified, blocks
 *             until resource is available.
 * @param arg  Argument provided by higher layer to open, in this case
 *             it must be a nrfx_adc_config_t
 *             configuration.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
nrf51_adc_open(struct os_dev *odev, uint32_t wait, void *arg)
{
    struct adc_dev *dev;
    nrfx_adc_config_t *cfg;
    int rc;

    if (arg == NULL) {
        rc = OS_EINVAL;
        goto err;
    }

    dev = (struct adc_dev *) odev;

    if (os_started()) {
        rc = os_mutex_pend(&dev->ad_lock, wait);
        if (rc != OS_OK) {
            goto err;
        }
    }

    /* Initialize the device */
    cfg = (nrfx_adc_config_t *)arg;
    rc = nrfx_adc_init(cfg, nrf51_adc_event_handler);
    if (rc != NRFX_SUCCESS) {
        goto err;
    }

    global_adc_dev = dev;
    global_adc_config = arg;

    return (0);
err:
    return (rc);
}


/**
 * Close the NRF51 ADC device.
 *
 * This function unlocks the device.
 *
 * @param odev The device to close.
 */
static int
nrf51_adc_close(struct os_dev *odev)
{
    struct adc_dev *dev;

    dev = (struct adc_dev *) odev;

    nrfx_adc_uninit();

    global_adc_dev = NULL;
    global_adc_config = NULL;

    if (os_started()) {
        os_mutex_release(&dev->ad_lock);
    }

    return (0);
}

/**
 * Configure an ADC channel on the Nordic ADC.
 *
 * @param dev The ADC device to configure
 * @param cnum The channel on the ADC device to configure
 * @param cfgdata An opaque pointer to channel config, expected to be
 *                a nrfx_adc_channel_config_t
 *
 * @return 0 on success, non-zero on failure.
 */
static int
nrf51_adc_configure_channel(struct adc_dev *dev, uint8_t cnum,
                            void *cfgdata)
{
    int rc;
    nrfx_adc_channel_config_t *cc_cfg;
    int reference;
    uint16_t refmv;
    uint8_t res;

    if (global_adc_config == NULL) {
        rc = OS_ERROR;
        goto err;
    }

    //store nrf_adc_chan for nrf51_adc_read_channel
    nrf_adc_chan = cfgdata;

    nrfx_adc_channel_enable(nrf_adc_chan);

    // they play shenanigans storing the reference bit fields so we have to as well
    cc_cfg = &nrf_adc_chan->config.config;
    reference = cc_cfg->reference | (cc_cfg->external_reference << ADC_CONFIG_EXTREFSEL_Pos);

    /* Set the resolution and reference voltage for this channel to
    * enable conversion functions.
    */
    switch (cc_cfg->resolution) {
        case NRF_ADC_CONFIG_RES_8BIT:
            res = 8;
            break;
        case NRF_ADC_CONFIG_RES_9BIT:
            res = 9;
            break;
        case NRF_ADC_CONFIG_RES_10BIT:
            res = 10;
            break;
        default:
            assert(0);
    }

    switch (reference) {
        case NRF_ADC_CONFIG_REF_VBG:
            refmv = 1200; /* 1.2V for NRF51 */
            break;
        case NRF_ADC_CONFIG_REF_EXT_REF0:
            refmv = init_adc_config->nadc_refmv0;
            break;
        case NRF_ADC_CONFIG_REF_EXT_REF1:
            refmv = init_adc_config->nadc_refmv1;
            break;
        case NRF_ADC_CONFIG_REF_SUPPLY_ONE_HALF:
            refmv = init_adc_config->nadc_refmv_vdd / 2;
            break;
        case NRF_ADC_CONFIG_REF_SUPPLY_ONE_THIRD:
            refmv = init_adc_config->nadc_refmv_vdd / 3;
            break;
        default:
            assert(0);
    }

    /* Adjust reference voltage for gain. */
    switch (cc_cfg->input) {
        case NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE:
            break;
        case NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD:
            refmv *= 3;
            break;
        case NRF_ADC_CONFIG_SCALING_INPUT_TWO_THIRDS:
            refmv = (refmv * 3) / 2;
            break;
        case NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD:
            refmv = refmv * 3;
            break;
        case NRF_ADC_CONFIG_SCALING_SUPPLY_TWO_THIRDS:
            refmv = (refmv * 3) / 2;
            break;
        default:
            break;
    }

    /* Store these values in channel definitions, for conversions to
     * milivolts.
     */
    dev->ad_chans[cnum].c_res = res;
    dev->ad_chans[cnum].c_refmv = refmv;
    dev->ad_chans[cnum].c_configured = 1;
    dev->ad_chans[cnum].c_cnum = cnum;

    return (0);
err:
    return (rc);
}

/**
 * Set buffer to read data into.  Implementation of setbuffer handler.
 * Sets both the primary and secondary buffers for DMA.
 */
static int
nrf51_adc_set_buffer(struct adc_dev *dev, void *buf1, void *buf2,
                     int buf_len)
{
    int rc;

    if (dev == NULL || buf1 == NULL) {
        rc = OS_EINVAL;
        goto err;
    }

    /* Convert overall buffer length, into a total number of samples which
     * Nordic APIs expect.
     */
    buf_len /= sizeof(nrf_adc_value_t);

    rc = nrfx_adc_buffer_convert((nrf_adc_value_t *) buf1, buf_len);
    if (rc != NRFX_SUCCESS) {
        goto err;
    }

    return (0);
err:
    return (rc);
}

//WHY DOES THIS EXIST! why doesnt it work without it!
static int
nrf51_adc_release_buffer(struct adc_dev *dev, void *buf, int buf_len)
{
    int rc;

    buf_len /= sizeof(nrf_adc_value_t);

    rc = nrfx_adc_buffer_convert((nrf_adc_value_t *) buf, buf_len);
    if (rc != NRFX_SUCCESS) {
        goto err;
    }

    return (0);
err:
    return (rc);
}

/**
 * Trigger an ADC sample.
 */
static int
nrf51_adc_sample(struct adc_dev *dev)
{
    nrfx_adc_sample();

    return (0);
}

/**
 * Blocking read of an ADC channel, returns result as an integer.
 * It is technically not necessary to have actually adc_chan_config (or even nrf51_adc_dev_init)
 * However there is no way to pass the nrfx_adc_channel_t argument through this function
 */
static int
nrf51_adc_read_channel(struct adc_dev *dev, uint8_t cnum, int *result)
{
    nrf_adc_value_t adc_value;
    int rc;

    rc = nrfx_adc_sample_convert(nrf_adc_chan, &adc_value);
    if (rc != NRFX_SUCCESS) {
        rc = OS_EBUSY;
        goto err;
    }

    *result = (int) adc_value;

    return 0;
err:
    return rc;
}

static int
nrf51_adc_read_buffer(struct adc_dev *dev, void *buf, int buf_len, int off,
                      int *result)
{
    nrf_adc_value_t val;
    int data_off;

    data_off = off * sizeof(nrf_adc_value_t);
    assert(data_off < buf_len);

    val = *(nrf_adc_value_t *) ((uint8_t *) buf + data_off);
    *result = val;

    return (0);
}

static int
nrf51_adc_size_buffer(struct adc_dev *dev, int chans, int samples)
{
    return (sizeof(nrf_adc_value_t) * chans * samples);
}

/**
 * ADC device driver functions
 */
static const struct adc_driver_funcs nrf51_adc_funcs = {
        .af_configure_channel = nrf51_adc_configure_channel,
        .af_sample = nrf51_adc_sample,
        .af_read_channel = nrf51_adc_read_channel,
        .af_set_buffer = nrf51_adc_set_buffer,
        .af_release_buffer = nrf51_adc_release_buffer,
        .af_read_buffer = nrf51_adc_read_buffer,
        .af_size_buffer = nrf51_adc_size_buffer,
};

/**
 * Callback to initialize an adc_dev structure from the os device
 * initialization callback.  This sets up a nrf51_adc_device(), so that
 * subsequent lookups to this device allow us to manipulate it.
 */
int
nrf51_adc_dev_init(struct os_dev *odev, void *arg)
{
    struct adc_dev *dev;

    dev = (struct adc_dev *) odev;

    os_mutex_init(&dev->ad_lock);

    dev->ad_chans = (void *) nrf51_adc_chans;
    dev->ad_chan_count = NRF_ADC_CHANNEL_COUNT;

    OS_DEV_SETHANDLERS(odev, nrf51_adc_open, nrf51_adc_close);

    assert(init_adc_config == NULL || init_adc_config == arg);
    init_adc_config = arg;

    dev->ad_funcs = &nrf51_adc_funcs;

    NVIC_SetVector(ADC_IRQn, (uint32_t) nrfx_adc_irq_handler);

    return (0);
}


