Merge branch 'master' of rakka.de:avr/thermocouple

Conflicts:
	firmware/Makefile.inc
	firmware/slavechip/Makefile
master
Paul Goeser 15 years ago
commit a0023a2c5a

@ -8,9 +8,6 @@ Where following values are Valid:
|--------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------------------------------------|
| Decimal Hex Name Address ValueL ValueH Reply Description| | Decimal Hex Name Address ValueL ValueH Reply Description|
|--------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------------------------------------|
| 0000001 0x01 Read-Temp Number of zeroes/Rand zeroes/Rand A 16Bit Value Reads the |
| Thermometer Representing Temperature|
| Starting with 0 the Temperature |
|--------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------------------------------------|
| 0000002 0x02 Read-Var8 Number of the zeroes/Rand zeroes/Rand A 8Bit Value Reads 8Bit | | 0000002 0x02 Read-Var8 Number of the zeroes/Rand zeroes/Rand A 8Bit Value Reads 8Bit |
| var-DEFINE read from VAR Variable | | var-DEFINE read from VAR Variable |
@ -21,10 +18,15 @@ Where following values are Valid:
| 0000004 0x04 Write-Var8 Number of the Value of Var zeroes/Rand zeroes/Rand Writes 8Bit| | 0000004 0x04 Write-Var8 Number of the Value of Var zeroes/Rand zeroes/Rand Writes 8Bit|
| var-DEFINE to write Variable | | var-DEFINE to write Variable |
|--------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------------------------------------|
| 0000005 0x05 Write-Var16 Number of the Value of Var Value of Var zeroes/Rand Writes 16 | | 0000005 0x05 Write-Var16 Number of the Value of Var Value of Var zeroes/Rand Writes 16 |
| var-DEFINE to write (HIGH) to write (LOW) Bit Var | | var-DEFINE to write (HIGH) to write (LOW) Bit Var |
|--------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------------------------------------|
| 0000006 0x06 Call-Func Number of the zeroes/Rand zeroes/Rand zeroes/Rand Calls a | | 0000006 0x06 Call-Func Number of the zeroes/Rand zeroes/Rand zeroes/Rand Calls a|
| func-DEFINE remote | | func-DEFINE remote |
function | | function |
|--------------------------------------------------------------------------------------------------------------------------|
| 0000001 0x01 Read-Temp Number of zeroes/Rand zeroes/Rand A 16Bit Value Reads the |
| Thermometer Representing Temperature|
| Starting with 0 the Temperature |
|--------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------------------------------------------------------------------------------------|

@ -3,6 +3,7 @@ CFLAGS += -save-temps
CFLAGS += -std=gnu99 -Wall # implements C99, for <util/atomic.h> CFLAGS += -std=gnu99 -Wall # implements C99, for <util/atomic.h>
# this removes dead code and does global linker optimization # this removes dead code and does global linker optimization
#CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax #CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax
CFLAGS += -Lm
include Makefile.inc include Makefile.inc

@ -2,7 +2,7 @@ CFLAGS += -save-temps
CFLAGS += -std=gnu99 -Wall # implements C99, for <util/atomic.h> CFLAGS += -std=gnu99 -Wall # implements C99, for <util/atomic.h>
# this removes dead code and does global linker optimization # this removes dead code and does global linker optimization
#CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax #CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax
CFLAGS += -Wall -Os -I. -mmcu=atmega88 CFLAGS += -Wall -Os -I. -mmcu=atmega88 -lm -ffunction-sections -fdata-sections -Wl,--relax -ffreestanding
# further optimization: # further optimization:
#CFLAGS += --param inline-call-cost=2 #CFLAGS += --param inline-call-cost=2

@ -255,7 +255,7 @@ void display_bar(int8_t value, int8_t min, int8_t max) {
} }
} }
void updateTemperature() { void displayTemperature() {
if(newThermoData==1) { if(newThermoData==1) {
newThermoData = 0; newThermoData = 0;

@ -38,6 +38,6 @@ extern void display_puthex(uint8_t outbyte);
extern void display_bar(int8_t value, int8_t min, int8_t max); extern void display_bar(int8_t value, int8_t min, int8_t max);
extern void display_putint(int16_t number); extern void display_putint(int16_t number);
extern void updateTemperature(); extern void displayTemperature();
#endif #endif

@ -17,7 +17,7 @@
#include "main.h" #include "main.h"
uint8_t newThermoData = 1; uint8_t newThermoData = 1;
uint16_t thermoData[] = {1024, 814, 2475, 2243}; uint16_t thermoData[];
void hardinit() { void hardinit() {
@ -75,52 +75,20 @@ int __attribute__((noreturn)) main(void) {
for(;;){ for(;;){
usbPoll(); usbPoll();
SOFTTIMER(2,500) { SOFTTIMER(2,800) {
thermoData[0]=thermoData[0]+5; uint16_t recv;
thermoData[1]=thermoData[1]+15; for(int i=0; i<4; i++) {
thermoData[2]=thermoData[2]+7; thermoData[i] = spi_master_transceive(7, i, 0);
thermoData[3]=thermoData[3]+18; }
newThermoData = 1; newThermoData = 1;
} }
SOFTTIMER(1,250) { SOFTTIMER(1,250) {
updateTemperature(); displayTemperature();
} }
/* SOFTTIMER(3,100) {
/* uint8_t foo[4];
foo[0]=0x55;
foo[1]=0x88;
foo[3]=0x23;
spi_mst_write_read(2,foo);
spi_mst_start_packet();
spi_mst_write_read(2,foo+2);
spi_mst_end_packet();
uint16_t foo=0x3456;
foo=spi_master_communicate(3,5,foo);
display_gotoyx(0,0);
display_puthex(foo[0]);
display_puthex(foo[1]);
display_puthex(foo[2]);
display_puthex(foo[3]);
display_puthex((foo>>8)&0xff);
display_puthex((foo)&0xff);
display_puts("\nfoo");
display_update();
}*/
} }
} }
/*
ISR(TIMER1_OVF_vect, ISR_NAKED){
asm volatile ("in %0, %1\n" : "=r" (sreg_store) : "I" (_SFR_IO_ADDR(SREG)));
timer1_acc++;
asm volatile ("out %1, %0\n" : "=r" (sreg_store) : "I" (_SFR_IO_ADDR(SREG)));
reti();
}*/
ISR(TIMER1_OVF_vect,ISR_NOBLOCK){ ISR(TIMER1_OVF_vect,ISR_NOBLOCK){
uint16_t tmp; uint16_t tmp;

@ -1,6 +1,10 @@
#include "spi_proto.h" #include "spi_proto.h"
#include "spi.h" #include "spi.h"
#ifndef SPI_MASTER
#include "main.h"
#endif
/***** MASTER *****/ /***** MASTER *****/
uint8_t mst_buf[5]; uint8_t mst_buf[5];
@ -90,8 +94,11 @@ uint16_t spi_proto_slaveaction(uint8_t opcode, uint8_t addr, uint16_t data) {
//TODO: prevent a function from being run several times because the message gets repeated. //TODO: prevent a function from being run several times because the message gets repeated.
break; break;
case 7: case 7:
//TODO #ifndef SPI_MASTER
retval = 0; if(addr < 4) {
retval = temperatures[addr];
} else return 0;
#endif
break; break;
default: default:
break; break;

@ -21,12 +21,6 @@ void call_func(uint8_t number);
/***** MASTER END *****/ /***** MASTER END *****/
/***** SLAVE *****/ /***** SLAVE *****/
/*
extern uint16_t *spi_proto_globals8[];
extern uint8_t *spi_proto_globals16[];
extern funptr_t spi_proto_funcs[];
*/
#include "spi_pointers.h" #include "spi_pointers.h"
uint16_t spi_proto_slaveaction(uint8_t opcode, uint8_t addr, uint16_t data); uint16_t spi_proto_slaveaction(uint8_t opcode, uint8_t addr, uint16_t data);

@ -2,7 +2,6 @@ include ../Makefile.inc
DEFINES += -DF_CPU=8000000 DEFINES += -DF_CPU=8000000
COMPILE = avr-gcc $(CFLAGS) $(DEFINES) COMPILE = avr-gcc $(CFLAGS) $(DEFINES)
OBJECTS = main.o mcp_adc.o i2c_simple.o softtimer.o spi_proto.o spi.o spi_pointers.o muxer.o debug.o OBJECTS = main.o mcp_adc.o i2c_simple.o softtimer.o spi_proto.o spi.o spi_pointers.o muxer.o debug.o
@ -46,7 +45,7 @@ clean:
# file targets: # file targets:
firmware.bin: $(OBJECTS) firmware.bin: $(OBJECTS)
$(COMPILE) -o firmware.bin $(OBJECTS) $(COMPILE) -lm -o firmware.bin -lm $(OBJECTS) -lm
firmware.hex: firmware.bin firmware.hex: firmware.bin
rm -f firmware.hex firmware.eep.hex rm -f firmware.hex firmware.eep.hex

@ -3,21 +3,14 @@
#include "muxer.h" #include "muxer.h"
#include "i2c_simple.h" #include "i2c_simple.h"
#include "mcp_adc.h" #include "mcp_adc.h"
#include "debug.h" #include "debug.h"
#include "math.h"
uint8_t foo;
uint16_t bar;
uint16_t timertmp; uint16_t timertmp;
uint16_t temperatures[4]; uint16_t temperatures[4];
uint8_t sensor_active[4];
int32_t temp_avg_cumul; int32_t temp_avg_cumul[4];
int16_t temp_avg_count; int16_t temp_avg_count[4];
void baz() {
foo++;
}
/* pinout /* pinout
* - i2c: * - i2c:
@ -26,6 +19,8 @@ void baz() {
* - multiplexer: * - multiplexer:
* C3: inhibit * C3: inhibit
* C0-C2: muxer select * C0-C2: muxer select
* - offset measurement
* D0-D3 offset compensation
* *
* *
* amp 0 is on muxer channel 2 * amp 0 is on muxer channel 2
@ -36,9 +31,66 @@ void baz() {
#define MUXER_CHANNEL_2 1 #define MUXER_CHANNEL_2 1
#define MUXER_CHANNEL_3 3 #define MUXER_CHANNEL_3 3
void hardinit() {
/* initializes the hardware */
int32_t avg_temp(int16_t val, uint8_t channel) {
int32_t temp = temp_avg_cumul[channel];
temp /= temp_avg_count[channel];
temp_avg_count[channel] = 0;
temp_avg_cumul[channel] = 0;
return (temp * 625); // nV
}
uint16_t calc_temp(int16_t val, uint8_t channel) {
float mV = ((float) avg_temp(val, channel))/1000000;
uint16_t temp;
if(mV < 0) {
/* t in mV
E = sum(i=0 to n) c_i t^i. ; n=10
*/
float coef[] = {
0.000000000000E+00,
0.394501280250E-01,
0.236223735980E-04,
-0.328589067840E-06,
-0.499048287770E-08,
-0.675090591730E-10,
-0.574103274280E-12,
-0.310888728940E-14,
-0.104516093650E-16,
-0.198892668780E-19,
-0.163226974860E-22
};
for(int i=0; i<11; i++) {
temp += coef[i] * pow(mV, i+1);
}
return temp;
} else {
/*
t in mV
E = sum(i=0 to n) c_i t^i + a0 exp(a1 (t - a2)^2). ; n = 9
*/
float coef[] = {
-0.176004136860E-01,
0.389212049750E-01,
0.185587700320E-04,
-0.994575928740E-07,
0.318409457190E-09,
-0.560728448890E-12,
0.560750590590E-15,
-0.320207200030E-18,
0.971511471520E-22,
-0.121047212750E-25
};
float a[] = {0.118597600000E+00, -0.118343200000E-03, 0.126968600000E+03};
for(int i=0; i<10; i++) {
temp += coef[i]*pow(mV, i+1) + a[0] * pow(exp(a[1]*(mV - a[2])), 2);
}
}
}
/* initializes the hardware */
void hardinit() {
// enable softtimer isr // enable softtimer isr
TCCR1A = _BV(WGM10); TCCR1A = _BV(WGM10);
TCCR1B = _BV(WGM12) | _BV(CS11); // clk/8 prescaler, 4kHz PWM-freq. TCCR1B = _BV(WGM12) | _BV(CS11); // clk/8 prescaler, 4kHz PWM-freq.
@ -47,6 +99,7 @@ void hardinit() {
spi_init(); spi_init();
muxer_init(); muxer_init();
offset_measure_init();
i2c_init(); i2c_init();
@ -54,53 +107,58 @@ void hardinit() {
} }
void softinit() { void softinit() {
//test values
foo = 0x87;
bar= 0xfafa;
mcpadc_init(ADC_GAIN_2|ADC_CONV_CONT|ADC_BITS_16); mcpadc_init(ADC_GAIN_2|ADC_CONV_CONT|ADC_BITS_16);
} }
int __attribute__((noreturn)) main(void) { int __attribute__((noreturn)) main(void) {
temperatures[2]=1;
hardinit(); hardinit();
temperatures[2]=10;
softinit(); softinit();
muxer_set(MUXER_CHANNEL_0); muxer_set(MUXER_CHANNEL_0);
temperatures[2]=0;
dbgLog("Hallo, Welt!\n");
for(;;){ for(;;){
SOFTTIMER(1,10) { SOFTTIMER(1,10) {
if(mcpadc_has_new_data()) { for(int i=0; i<4; i++) {
temperatures[0] = mcpadc_get_data(); if(sensor_active[i] && mcpadc_has_new_data(i)) {
temperatures[2]++; temperatures[i] = calc_temp( mcpadc_get_data(i), i );
int16_t temp = temperatures[0]; temp_avg_cumul[i] += temperatures[i];
temp_avg_cumul += temp; temp_avg_count[i] += 1;
temp_avg_count += 1; }
} }
temperatures[1] = 22;
} }
SOFTTIMER(2,500){ SOFTTIMER(2,500){
int32_t temp = temp_avg_cumul; for(int i=0; i<4; i++) {
temp /= temp_avg_count; if(sensor_active[i]) {
temp_avg_count = 0; temp_avg_cumul = 0; int32_t temp = temp_avg_cumul[i];
int32_t nV = (temp * 625); temp /= temp_avg_count[i];
int32_t mK = nV/39; temp_avg_count[i] = 0; temp_avg_cumul[i] = 0;
int32_t nV = (temp * 625);
int32_t mK = nV/39;
dbgLog("temp-%i: %6li (%li µV, %li mK)\n",i,temp,nV/1000, mK);
}
}
}
dbgLog("temp: %6li (%li µV, %li mK)\n",temp,nV/1000, mK); SOFTTIMER(3,4000){
static uint8_t toggle;
if(toggle){
offset_measure_start(0);
toggle=0;
dbgLog("measuring offset\n");
} else {
offset_measure_stop();
toggle=1;
dbgLog("stopping offset-measuring\n");
}
} }
} }
} }
ISR(TIMER1_OVF_vect,ISR_NOBLOCK){ ISR(TIMER1_OVF_vect,ISR_NOBLOCK){
timertmp=timer1_acc; timertmp=timer1_acc;
timertmp++; timertmp++;

@ -14,11 +14,7 @@
#include "softtimer.h" #include "softtimer.h"
#include "debug.h" #include "debug.h"
extern uint8_t foo;
extern uint16_t bar;
extern uint16_t timertmp; extern uint16_t timertmp;
extern uint16_t temperatures[]; extern uint16_t temperatures[];
void baz();
#endif //__MAIN_H #endif //__MAIN_H

@ -42,8 +42,10 @@ void mcpadc_init(uint8_t mode)
curmode = mode; curmode = mode;
} }
uint8_t mcpadc_has_new_data(void) uint8_t mcpadc_has_new_data(uint8_t channel)
{ {
// TODO: implement channel
/* this assumes that the first RDY bit read after the sample data indicates the old/new state of the sample we just read */ /* 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){ if(unread_data_available){
// we already have new data, don't overwrite that by reading more // we already have new data, don't overwrite that by reading more
@ -69,8 +71,9 @@ uint8_t mcpadc_has_new_data(void)
} }
#if ADC_ENABLE_18_BIT_MODE #if ADC_ENABLE_18_BIT_MODE
int32_t mcpadc_get_data(void) int32_t mcpadc_get_data(uint8_t channel)
{ {
// TODO: implement channel
if(!unread_data_available){ if(!unread_data_available){
return 0; return 0;
} }
@ -86,7 +89,7 @@ int32_t mcpadc_get_data(void)
return value; return value;
} }
#else #else
int16_t mcpadc_get_data(void) int16_t mcpadc_get_data(uint8_t channel)
{ {
if(!unread_data_available){ if(!unread_data_available){
return 0; return 0;

@ -26,15 +26,15 @@ void mcpadc_init(uint8_t mode);
/* tests if the adc has a new sample /* tests if the adc has a new sample
* returns nonzero if new data is aviable, 0 otherwise * returns nonzero if new data is aviable, 0 otherwise
*/ */
uint8_t mcpadc_has_new_data(void); uint8_t mcpadc_has_new_data(uint8_t channel);
/* returns the most recent sample result of the adc /* returns the most recent sample result of the adc
* !! return type depends on defines * !! return type depends on defines
*/ */
#if ADC_ENABLE_18_BIT_MODE #if ADC_ENABLE_18_BIT_MODE
int32_t mcpadc_get_data(void); int32_t mcpadc_get_data(uint8_t channel);
#else #else
int16_t mcpadc_get_data(void); int16_t mcpadc_get_data(uint8_t channel);
#endif #endif
/* instructs the adc to take a new sample now /* instructs the adc to take a new sample now

@ -14,3 +14,19 @@ void muxer_set(uint8_t channel){
//TODO: delays, check everything, mask in register //TODO: delays, check everything, mask in register
} }
void offset_measure_init(){
DDRD |= 0x0f; // first 4 pins as output
// PORTD = 0x00; // turn everything off
}
void offset_measure_start(uint8_t channel){
if(channel >3){
return;
}
PORTD |= (1<<channel);
}
void offset_measure_stop(){
PORTD &= ~0x0f;
}

@ -4,3 +4,7 @@
void muxer_init(); void muxer_init();
void muxer_set(uint8_t channel); void muxer_set(uint8_t channel);
void offset_measure_init();
void offset_measure_start(uint8_t channel);
void offset_measure_stop();

@ -7,18 +7,9 @@ uint8_t *spi_proto_globals8[] = {
}; };
uint16_t *spi_proto_globals16[] = { uint16_t *spi_proto_globals16[] = {
&timertmp,
&temperatures[0],
&temperatures[1],
&temperatures[2],
&temperatures[3],
}; };
funptr_t spi_proto_funcs[] = { funptr_t spi_proto_funcs[] = {
&dbgHasNew, &dbgHasNew,
&dbgAdvanceChar &dbgAdvanceChar
}; };

Loading…
Cancel
Save