--- /dev/null
+
+
+//// ADC ADS1018 Definitions
+// SS "Single-shot conversion start"
+#define ADS_SConv (1 << 15)
+// MUX "Input multiplexer"
+#define ADS_MUX_AIN1_GND (0b101 << 12)
+#define ADS_MUX_AIN0_AIN3 (0b001 << 12)
+// PGA "programmable gain amplifier"
+#define ADS_GAIN_4V (0b001 << 9)
+#define ADS_GAIN_2V (0b010 << 9)
+#define ADS_GAIN_1V (0b011 << 9)
+#define ADS_GAIN_025V (0b111 << 9)
+// MODE "device operating mode"
+#define ADS_MODE_S (1 << 8)
+// DR "Data rate"
+#define ADS_1600SPS (0b100 << 5)
+#define ADS_128SPS (0b000 << 5)
+// PULL_UP_EN "Pull-up enable"
+#define ADS_PULLUP_DRDY (1 << 3)
+// NOP "No operation"
+#define ADS_WRITE_CONFIG (0b01 << 1)
+
//CPU Regs
//Init ADC SPI
- SPCR = (0 << SPIE) | (1 << SPE ) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (0 << SPR0);
- SPSR = (1 << SPI2X); //fcpu/8
+ SPCR = (0 << SPIE) | (1 << SPE ) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (1 << CPHA) | (0 << SPR0);
+ SPSR = (1 << SPI2X); //fcpu/2
DDRB |= (1 << PB7) | (1 << PB5) | (1 << PB4); //ADC has three control lines
//Init ADC for presence measurement
- ADMUX = (3 << REFS0) | (1 << ADLAR) | (3 << MUX0);
+ ADMUX = (3 << REFS0) | (1 << ADLAR) | (3 << MUX0); // internal2.56V ADC3
ADCSRA = (1 << ADEN) | (0 << ADIE) | (5 << ADPS0); //fcpu/32
DIDR0 = 0x08; //PA3 is analog only
#include "main.h"
+#include "ads_adc.h"
+#define CONNECTED_SENSORS 8
-uint8_t connected_sensors = 0x1a;
uint8_t measurement_step;
+uint8_t current_channel = 0;
//factors: gain_current has 2^29, ADC has 2^7 steps per mV
//34 read ADC temperature as 9th channel
//35 send ADC temperature
-
void do_measurement_step(void) {
- if(measurement_step == 0) {
- LED1_ON();
- }
- else if(measurement_step == 36) {
- measurement_active = 0;
- LED1_OFF();
+ if(measurement_step < (CONNECTED_SENSORS*4) && measurement_step & 0x3 == 0x0) {
+ LED1_ON();
+ select_channel();
+ }
+ else if(measurement_step < (CONNECTED_SENSORS*4) && measurement_step & 0x3 == 0x1) {
+ ADCSRA |= (1<<ADSC); //start ADC conversion
+ uint16_t conf_register = (ADS_MODE_S | ADS_GAIN_025V |
+ ADS_SConv | ADS_WRITE_CONFIG | ADS_PULLUP_DRDY | ADS_1600SPS);
+ conf_register |= ADS_MUX_AIN0_AIN3;
+ SPI_transceive_16bit(conf_register);
+ }
+ else if(measurement_step < (CONNECTED_SENSORS*4) && measurement_step & 0x3 == 0x2) {
+ set_inhibit_signals(1);
+ uint16_t x;
+ // read on / off
+ x = ADCL;
+ x += (ADCH<<8);
+ // should be
+ // (5 - 2.2E3 * 410E-6) / 2 = 2.049 V if on
+ // (5 - 2.2E3 * 10E-6) / 2 = 2.489 V if off
+ // -> compare to 2.27 V or (2.27/2.56)*2^16 = 58112
+ if (x < 58112) {
+ // read value
+ x = SPI_transceive_16bit(0x0000);
+ x = res_to_temp(adc_to_res(x));
+ void send_answer_hex(0, 0, x);
+ }
+ else {
+ void send_answer_hex(0, 0, (1<< (5*4)));
+ }
+ else if(measurement_step < (CONNECTED_SENSORS*4) && measurement_step & 0x3 == 0x3) {
+ selected_channel += 1;
+ }
+ measurement_step += 1;
+ if(measurement_step == 36)
measurement_step = 0;
+ selected_channel = 0
+ LED1_OFF();
+ measurement_active = 0;
+ }
+
+
+void set_inhibit_signals(int on_off) {
+ PORTC = (PORTC & 0x3F) | (on_off << 6);
+ }
+
+void select_channel() {
+ if (current_channel == 8) {
+ // temperature measurement
+ set_inhibit_signals(0);
}
+ else {
+ // update the select outputs
+ PORTA = (PORTA & 0x8F) | (current_channel << 4);
+ // clear inhibit signals
+ set_inhibit_signals(0);
+ }
+ }
+
+uint16_t SPI_transceive_16bit(uint16_t data){
+ char high, low;
+ high = SPI_transceive(data>>8);
+ low = SPI_transceive(data&0xFF);
+ return (high << 8) | low;
}
+
+char SPI_transceive(unsigned char cData){
+ SPDR = cData;
+ while (!(SPSR & (1<<SPIF)))
+ ;
+ return SPDR;
+ }
\ No newline at end of file