Skip to content

Commit

Permalink
add support for external TWI ADC
Browse files Browse the repository at this point in the history
  • Loading branch information
wertarbyte committed Jun 22, 2012
1 parent 6f3c134 commit 3d64060
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
MCU = atmega8
F_CPU = 8000000
TARGET = funkenschlag
SRC = funkenschlag.c serial.c src_adc.c src_sw.c src_ds.c datenschlag.c
SRC = funkenschlag.c serial.c twi.c src_adc.c src_sw.c src_ds.c src_twi_adc.c datenschlag.c
COMBINE_SRC = 0

include avr-tmpl.mk
8 changes: 7 additions & 1 deletion config.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
/*** Funkenschlag configuration file ***/

// use TWI?
//#define ENABLE_TWI

/* ADC configuration */

// enable ADC4 and ADC5 - this disables I²C!
// enable ADC4 and ADC5 - cannot be used in conjunction with TWI/I²c!
//#define USE_ADC4_ADC5

// enable PCF 8159 ADC via TWI
//#define USE_TWI_ADC

/* Datenschlag configuration */

#define DS_RETRANSMITS 0
Expand Down
21 changes: 21 additions & 0 deletions funkenschlag.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
#include <util/delay.h>
#include "config.h"
#include "serial.h"
#include "twi.h"
#include "src_adc.h"
#include "src_sw.h"
#include "src_ds.h"
#include "src_twi_adc.h"
#include "datenschlag.h"
#include "datenschlag_structs.h"

Expand All @@ -36,6 +38,7 @@
#define SRC_ADC 1
#define SRC_SW 2
#define SRC_DS 3
#define SRC_TWI_ADC 4
#define SRC_ID(s,n) ( (((s)&0x0F)<<4) | ((n)&0x0F) )

#define SRC_SYS(n) ((n)>>4)
Expand All @@ -51,6 +54,9 @@ static uint8_t channel_source[] = {
#ifdef USE_ADC4_ADC5
SRC_ID(SRC_ADC, 4),
SRC_ID(SRC_ADC, 5),
#elif defined(USE_TWI_ADC)
SRC_ID(SRC_TWI_ADC, 0),
SRC_ID(SRC_TWI_ADC, 1),
#endif
};

Expand Down Expand Up @@ -84,6 +90,9 @@ static int16_t get_channel(uint8_t i) {
case SRC_DS:
val = ds_get_next_pulse();
break;
case SRC_TWI_ADC:
val = twi_adc_get(SRC_NUM(src));
break;
default: /* unknown source */
break;
}
Expand Down Expand Up @@ -125,13 +134,20 @@ int main(void) {
VOL_PORT |= (1<<VOL_BIT); // enable pullup

serial_init();
#ifdef ENABLE_TWI
twi_init();
#endif

/* configure switches */
sw_init();

/* configure ADC */
adc_init();

#if defined(USE_TWI_ADC)
twi_adc_init();
#endif

/* configure watchfog timer to reset after 60ms */
wdt_enable(WDTO_60MS);

Expand Down Expand Up @@ -187,6 +203,11 @@ int main(void) {
/* prepare Datenschlag data frames */
ds_prepare();

#ifdef USE_TWI_ADC
/* query TWI/I²C ADC */
twi_adc_query();
#endif

/* check voltage */
if ((~VOL_PIN) & 1<<VOL_BIT) {
// everything OK
Expand Down
48 changes: 48 additions & 0 deletions src_twi_adc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include "config.h"
#include "serial.h"
#include "src_twi_adc.h"
#include "twi.h"

/* PCF8591 I²C ADC/DAC */
#define TWI_ADC_ADDR 0x48
#define TWI_ADC_CHANNELS 4

uint16_t twi_adc_raw [TWI_ADC_CHANNELS] = {0};
int16_t twi_adc_values[TWI_ADC_CHANNELS] = {0};

static int16_t read_adc(uint8_t adc) {
uint8_t result = 0;
twi_start(TWI_ADC_ADDR<<1);
twi_write(adc);
twi_stop();
twi_start((TWI_ADC_ADDR<<1) | 1);
twi_read(1); /* discard first response */
result = twi_read(0);
return result;
}

int16_t twi_adc_get(uint8_t n) {
return twi_adc_values[n];
}

uint16_t twi_adc_get_raw(uint8_t n) {
return twi_adc_raw[n];
}

void twi_adc_query(void) {
/* keep sampling adc data */
for (uint8_t adc = 0; adc < TWI_ADC_CHANNELS; adc++) {
/* scale to 10 bit values */
twi_adc_raw[adc] = read_adc(adc);
twi_adc_values[adc] = twi_adc_raw[adc]<<2;
}
}

void twi_adc_init(void) {
}
4 changes: 4 additions & 0 deletions src_twi_adc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
void twi_adc_init(void);
void twi_adc_query(void);
int16_t twi_adc_get(uint8_t n);
uint16_t twi_adc_get_raw(uint8_t n);
44 changes: 44 additions & 0 deletions twi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/twi.h>
#include "twi.h"

void twi_init(void) {
TWSR = 0;
TWBR = (F_CPU / 100000UL - 16) / 2;
TWCR = 1<<TWEN;
}

static void twi_wait(void) {
while (!(TWCR & (1<<TWINT)));
}

void twi_start(uint8_t addr) {
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
twi_wait();
TWDR = addr;
TWCR = (1<<TWINT) | (1<<TWEN);
twi_wait();
}

void twi_stop(void) {
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}

void twi_write(uint8_t data) {
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
twi_wait();
}

uint8_t twi_read(uint8_t ack) {
TWCR = (1<<TWINT) | (1<<TWEN) | (ack? (1<<TWEA) : 0);
twi_wait();
uint8_t result = TWDR;
if (!ack) twi_stop();
return result;
}
5 changes: 5 additions & 0 deletions twi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
void twi_init(void);
void twi_start(uint8_t addr);
void twi_stop(void);
uint8_t twi_read(uint8_t ack);
void twi_write(uint8_t data);

0 comments on commit 3d64060

Please sign in to comment.