#include <stdint.h>
#include <string.h>

#include "nrf_adc.h"
#include "nrf_gpio.h"
#include "nrf_soc.h"
#include "app_util_platform.h"
#include "ba.h"
#include "io.h"
#include "nrf_drv_adc.h"
#include "nrf_delay.h"

//Not used:
//#include "ccs\ccsmox_common.h"
//#include "ccs\ccsmox_profiles.h"

// static void configure_io_pins(void);
//static void init_breathalyser();
static uint8_t m_sensor_scale_mode;
static uint8_t m_avg_mode;
static uint16_t m_vref_target;
//static uint8_t ccs_mox_profile[PROFILE_BLOCK_SIZE] = {0};
//static CcsConf ccs_mox_conf = {TYPE_BREATHALYSER, PROFILE_BLOCK_SIZE, 
//                                (uintptr_t)&ccs_mox_profile};
static uint16_t ccs_mox_samples[120] = {0};
static uint8_t ccs_mox_sample_size = 120;
static uint8_t ccs_mox_index;

/*
void configure_io_pins(void)
{
  nrf_gpio_cfg_output(IO_BA_SENSOR_ENABLE);
  nrf_gpio_pin_clear(IO_BA_SENSOR_ENABLE);
}
*/

/*
void init_breathalyser()
{
  memcpy(&ccs_mox_profile, &CCS_PROFILE_BREATHALYSER, PROFILE_BLOCK_SIZE);
  // Initialise library for breathalyser measurements
  //ccsmox_set_conf(CONF_SET_PROFILE, (uintptr_t)&ccs_mox_conf, sizeof(ccs_mox_conf));
}
*/

void ba_init()
{
//  configure_io_pins();
//  init_breathalyser();
  ba_set_adc_mode(BA_ADC_SCALING_INPUT_ONE_THIRD);
  nrf_adc_config_t nrf_adc_config = NRF_ADC_CONFIG_DEFAULT;
  // Initialize and configure ADC
  nrf_adc_configure(&nrf_adc_config);
  ret_code_t ret_code;
  nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;
  ret_code = nrf_drv_adc_init(&config, 0);
  APP_ERROR_CHECK(ret_code);
  m_vref_target = 1600;
  ba_set_adc_mode(BA_ADC_FULL_SCALE);
}

void ba_set_adc_mode(int mode)
{
  nrf_adc_config_t nrf_adc_config = NRF_ADC_CONFIG_DEFAULT;
  m_sensor_scale_mode = mode;
  switch(mode)
  {
    case BA_ADC_FULL_SCALE:
      nrf_adc_config.scaling = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE;
    break;
    case BA_ADC_SCALING_INPUT_TWO_THIRDS:
      nrf_adc_config.scaling = NRF_ADC_CONFIG_SCALING_INPUT_TWO_THIRDS;
    break;
    default:
	case BA_ADC_SCALING_INPUT_ONE_THIRD:
          m_sensor_scale_mode = BA_ADC_SCALING_INPUT_ONE_THIRD;
          nrf_adc_config.scaling = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
        break;
  }
  nrf_adc_configure(&nrf_adc_config);
}

/*void ba_init_ppm()
{
  ccs_mox_index = 0;
  //turn on the sensor
  //ba_set_sensor_enable(1);
}*/

/*void ba_set_vref_target(uint16_t mv)
{
  if( (mv > 1000) & (mv < 5000) )
  {
    m_vref_target = mv;
  }
}*/

/*uint16_t ba_vref_target()
{
  return m_vref_target;
}*/

/*void ba_set_avg_mode(int mode)
{
  switch(mode)
  {
    case BA_AVG_MODE_AVG:
    case BA_AVG_MODE_RAW:
    case BA_AVG_MODE_SUM:
      m_avg_mode = mode;
    break;
    default:
      m_avg_mode = BA_AVG_MODE_SUM;
    break;  
  }
}*/

/*int16_t ba_get_ppm_sample()
{
  uint16_t sample;
  int i;
  int samples;
  sample = 0;
  if( m_avg_mode == BA_AVG_MODE_RAW )
  {
    samples = 1;
  } 
  else 
  {
    samples = 4;
  }
  if( ccs_mox_index < ccs_mox_sample_size )
  {
    for(i=0; i < samples; i++)
    {
      //take 4 samples in a row to upconvert to 12-bit right justified data
      sample += nrf_adc_convert_single(NRF_ADC_CONFIG_INPUT_2);
    }
    ccs_mox_samples[ccs_mox_index] = sample;
    ccs_mox_index++;
    nrf_delay_ms(5);
  }
  if( m_avg_mode == BA_AVG_MODE_AVG )
  {
    sample = (sample + 2) / 4;
  }
  sample = sample * 1200 / m_vref_target;
  return sample;
}*/

/*uint8_t ba_is_ppm_done()
{
  return ccs_mox_index == ccs_mox_sample_size;
}*/

/*int ba_calc_ppm_bac()
{
  int ppm;
  ppm = 0; //ccsmox_803_set_data((uintptr_t)ccs_mox_samples, ccs_mox_sample_size);
  //todo convert PPM to BAC
  //turn off the sensor
  //ba_set_sensor_enable(0);
  return ppm;
}*/

int32_t ba_read_sensor()
{
  return nrf_adc_convert_single(NRF_ADC_CONFIG_INPUT_2);
}

/*float ba_calc_bac(int32_t first, int32_t min)
{
  float tmp;
  float bac;
  if (min > first)
  {
    bac = 0.0;
  } 
  else 
  {
    tmp = (float) first / (float) min;
    bac = (0.4283 * tmp) - 0.4283;
  }
  return bac;
}*/

/*void ba_print_bac(char * str, float bac)
{
  int32_t tmp = bac*1000;
  sprintf(str, "%i.%02i", (int)tmp/1000, ((int)tmp % 1000)/10);
}

int32_t ba_calc_mv(int32_t sample)
{
  return (sample * 3600 + 511) / 1023;
}*/

int32_t ba_read_sensor_mv()
{
  return ba_calc_mv( ba_read_sensor() );
}

int32_t ba_read_battery()
{
  int32_t value;
  uint8_t mode = m_sensor_scale_mode;
  ba_set_adc_mode(BA_ADC_SCALING_INPUT_ONE_THIRD);
  nrf_delay_ms(3);
  value = nrf_adc_convert_single(NRF_ADC_CONFIG_INPUT_3);
  ba_set_adc_mode(mode);
  return value;
}

int32_t ba_read_battery_mv()
{
  return ba_calc_mv( ba_read_battery() );
}


/*void ba_set_sensor_enable(uint8_t enabled)
{
  if ( enabled )
  {
    nrf_gpio_pin_set(IO_BA_SENSOR_ENABLE);
  } 
  else 
  {
    nrf_gpio_pin_clear(IO_BA_SENSOR_ENABLE);
  }
}*/
