#include <stdint.h>

#include "i2c_simple.h"

#include "mcp_adc.h"

/* analog digital converter
 * scratchpad
 * 
 * address: 1101000
 * read: conv data: 2 byte + config
 * - ignore first 2 bits, bit 3 = MSB/sign
 * - keeping reading always gets config byte
 * write: config
 * 
 * configuration register:
 * - 0x15 continuos conversion, 14bit, gain x2 (page 16)
 * - 0x05 single conversion, 14bit, gain x2 (page 16)
 * bit 7 low -> new data, set to 1 on single conv mode to init
 *
 */


#define ADC_NEW_SAMPLE 0x80
#define ADC_READ_DATA 0x40

#define ADC_BITS_MASK 0x0c

#define ADC_ADDR 0xD0 /* or 0x68 */

uint8_t r[4];
uint8_t curmode;

void mcpadc_init(uint8_t mode)
{
	i2c_write(ADC_ADDR, 1, &mode);
	curmode = mode;
}

uint8_t mcpadc_has_new_data(void)
{
	/* this assumes that the first RDY bit read after the sample data indicates the old/new state of the sample we just read */
#if ADC_ENABLE_18_BIT_MODE
	if(curmode & ADC_BITS_MASK == ADC_BITS_18)
	{
		i2c_read(ADC_ADDR, 4, r);
		curmode = r[3];
	}
	else
#endif
	{
		i2c_read(ADC_ADDR, 3, r);
		curmode = r[2];
	}
	if(~curmode & ADC_NEW_SAMPLE) {curmode &= ADC_READ_DATA;}
	return ~curmode & ADC_READ_DATA;
}

#if ADC_ENABLE_18_BIT_MODE
int32_t mcpadc_get_data(void)
{
	int32_t value = 0;
	if(r[0] & 0x80) {value = 0xffff;}
	value = (value << 16) | (r[0] << 8) | r[1];
	if((uint8_t) r[3] & ADC_BITS_MASK == ADC_BITS_18)
	{
		value = (value << 8) | r[2];
	}
	curmode |= (ADC_NEW_SAMPLE & ADC_READ_DATA);
	return value;
}
#else
int16_t mcpadc_get_data(void)
{
	int16_t value = (r[0] << 8) | r[1];
	curmode |= (ADC_NEW_SAMPLE & ADC_READ_DATA);
	return value;
}
#endif

void mcpadc_start_conv(void)
{
	r[3] = curmode | ADC_NEW_SAMPLE;
	i2c_write(ADC_ADDR, 1, &(r[3]));
	curmode |= (ADC_NEW_SAMPLE & ADC_READ_DATA);/* you asked for a new sample - no you won't get the old one */
}
