#include #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; uint8_t unread_data_available; void mcpadc_init(uint8_t mode) { int written = i2c_write(ADC_ADDR, 1, &mode); if(written!=1){ for(;;); //TODO: error reporting } 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(unread_data_available){ // we already have new data, don't overwrite that by reading more return unread_data_available; } #if ADC_ENABLE_18_BIT_MODE if(curmode & ADC_BITS_MASK == ADC_BITS_18) { i2c_read(ADC_ADDR, 4, r); curmode = r[3]; } else #else { i2c_read(ADC_ADDR, 3, r); curmode = r[2]; } #endif if(!(curmode & ADC_NEW_SAMPLE)){ // if the /RDY bit reads 0, we just read a new sample unread_data_available = 1; } return unread_data_available; } #if ADC_ENABLE_18_BIT_MODE int32_t mcpadc_get_data(void) { if(!unread_data_available){ return 0; } 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); unread_data_available = 0; return value; } #else int16_t mcpadc_get_data(void) { if(!unread_data_available){ return 0; } int16_t value = (r[0] << 8) | r[1]; curmode |= (ADC_NEW_SAMPLE & ADC_READ_DATA); unread_data_available = 0; 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 */ unread_data_available = 0; }