diff --git a/documentation/SPI-Proto b/documentation/SPI-Proto index 5f36039..56c3441 100644 --- a/documentation/SPI-Proto +++ b/documentation/SPI-Proto @@ -8,9 +8,6 @@ Where following values are Valid: |--------------------------------------------------------------------------------------------------------------------------| | 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 | | 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| | 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 | |--------------------------------------------------------------------------------------------------------------------------| -| 0000006 0x06 Call-Func Number of the zeroes/Rand zeroes/Rand zeroes/Rand Calls a | -| func-DEFINE remote | - function | +| 0000006 0x06 Call-Func Number of the zeroes/Rand zeroes/Rand zeroes/Rand Calls a| +| func-DEFINE remote | +| function | +|--------------------------------------------------------------------------------------------------------------------------| + +| 0000001 0x01 Read-Temp Number of zeroes/Rand zeroes/Rand A 16Bit Value Reads the | +| Thermometer Representing Temperature| +| Starting with 0 the Temperature | |--------------------------------------------------------------------------------------------------------------------------| diff --git a/firmware/Makefile b/firmware/Makefile index 314a301..4c3776b 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -3,6 +3,7 @@ CFLAGS += -save-temps CFLAGS += -std=gnu99 -Wall # implements C99, for # this removes dead code and does global linker optimization #CFLAGS += -ffunction-sections -Wl,--gc-sections -Wl,--relax +CFLAGS += -Lm include Makefile.inc diff --git a/firmware/Makefile.inc b/firmware/Makefile.inc index 466ab25..56c4ba1 100644 --- a/firmware/Makefile.inc +++ b/firmware/Makefile.inc @@ -2,7 +2,7 @@ CFLAGS += -save-temps CFLAGS += -std=gnu99 -Wall # implements C99, for # this removes dead code and does global linker optimization #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: #CFLAGS += --param inline-call-cost=2 diff --git a/firmware/masterchip/display.c b/firmware/masterchip/display.c index 3b9b18e..72dd35c 100644 --- a/firmware/masterchip/display.c +++ b/firmware/masterchip/display.c @@ -255,7 +255,7 @@ void display_bar(int8_t value, int8_t min, int8_t max) { } } -void updateTemperature() { +void displayTemperature() { if(newThermoData==1) { newThermoData = 0; diff --git a/firmware/masterchip/display.h b/firmware/masterchip/display.h index 8f433f8..423a966 100644 --- a/firmware/masterchip/display.h +++ b/firmware/masterchip/display.h @@ -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_putint(int16_t number); -extern void updateTemperature(); +extern void displayTemperature(); #endif diff --git a/firmware/masterchip/main.c b/firmware/masterchip/main.c index e9a13af..3977576 100644 --- a/firmware/masterchip/main.c +++ b/firmware/masterchip/main.c @@ -17,7 +17,7 @@ #include "main.h" uint8_t newThermoData = 1; -uint16_t thermoData[] = {1024, 814, 2475, 2243}; +uint16_t thermoData[]; void hardinit() { @@ -75,52 +75,20 @@ int __attribute__((noreturn)) main(void) { for(;;){ usbPoll(); - SOFTTIMER(2,500) { - thermoData[0]=thermoData[0]+5; - thermoData[1]=thermoData[1]+15; - thermoData[2]=thermoData[2]+7; - thermoData[3]=thermoData[3]+18; - newThermoData = 1; + SOFTTIMER(2,800) { + uint16_t recv; + for(int i=0; i<4; i++) { + thermoData[i] = spi_master_transceive(7, i, 0); + } + newThermoData = 1; } 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){ uint16_t tmp; diff --git a/firmware/shared/spi_proto.c b/firmware/shared/spi_proto.c index 857f9e2..4dda941 100644 --- a/firmware/shared/spi_proto.c +++ b/firmware/shared/spi_proto.c @@ -1,6 +1,10 @@ #include "spi_proto.h" #include "spi.h" +#ifndef SPI_MASTER +#include "main.h" +#endif + /***** MASTER *****/ 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. break; case 7: - //TODO - retval = 0; +#ifndef SPI_MASTER + if(addr < 4) { + retval = temperatures[addr]; + } else return 0; +#endif break; default: break; diff --git a/firmware/shared/spi_proto.h b/firmware/shared/spi_proto.h index e410236..cb9f0a7 100644 --- a/firmware/shared/spi_proto.h +++ b/firmware/shared/spi_proto.h @@ -21,12 +21,6 @@ void call_func(uint8_t number); /***** MASTER END *****/ /***** SLAVE *****/ - -/* -extern uint16_t *spi_proto_globals8[]; -extern uint8_t *spi_proto_globals16[]; -extern funptr_t spi_proto_funcs[]; -*/ #include "spi_pointers.h" uint16_t spi_proto_slaveaction(uint8_t opcode, uint8_t addr, uint16_t data); diff --git a/firmware/slavechip/Makefile b/firmware/slavechip/Makefile index d996db6..f59158b 100644 --- a/firmware/slavechip/Makefile +++ b/firmware/slavechip/Makefile @@ -2,7 +2,6 @@ include ../Makefile.inc DEFINES += -DF_CPU=8000000 - 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 @@ -46,7 +45,7 @@ clean: # file targets: firmware.bin: $(OBJECTS) - $(COMPILE) -o firmware.bin $(OBJECTS) + $(COMPILE) -lm -o firmware.bin -lm $(OBJECTS) -lm firmware.hex: firmware.bin rm -f firmware.hex firmware.eep.hex diff --git a/firmware/slavechip/main.c b/firmware/slavechip/main.c index ae317b3..f0fe4da 100644 --- a/firmware/slavechip/main.c +++ b/firmware/slavechip/main.c @@ -3,21 +3,14 @@ #include "muxer.h" #include "i2c_simple.h" #include "mcp_adc.h" - #include "debug.h" +#include "math.h" -uint8_t foo; -uint16_t bar; uint16_t timertmp; uint16_t temperatures[4]; - -int32_t temp_avg_cumul; -int16_t temp_avg_count; - - -void baz() { - foo++; -} +uint8_t sensor_active[4]; +int32_t temp_avg_cumul[4]; +int16_t temp_avg_count[4]; /* pinout * - i2c: @@ -26,6 +19,8 @@ void baz() { * - multiplexer: * C3: inhibit * C0-C2: muxer select + * - offset measurement + * D0-D3 offset compensation * * * amp 0 is on muxer channel 2 @@ -36,9 +31,66 @@ void baz() { #define MUXER_CHANNEL_2 1 #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 TCCR1A = _BV(WGM10); TCCR1B = _BV(WGM12) | _BV(CS11); // clk/8 prescaler, 4kHz PWM-freq. @@ -47,6 +99,7 @@ void hardinit() { spi_init(); muxer_init(); + offset_measure_init(); i2c_init(); @@ -54,53 +107,58 @@ void hardinit() { } void softinit() { - - //test values - foo = 0x87; - bar= 0xfafa; - mcpadc_init(ADC_GAIN_2|ADC_CONV_CONT|ADC_BITS_16); - } int __attribute__((noreturn)) main(void) { - temperatures[2]=1; hardinit(); - temperatures[2]=10; softinit(); muxer_set(MUXER_CHANNEL_0); - temperatures[2]=0; - dbgLog("Hallo, Welt!\n"); for(;;){ SOFTTIMER(1,10) { - if(mcpadc_has_new_data()) { - temperatures[0] = mcpadc_get_data(); - temperatures[2]++; - int16_t temp = temperatures[0]; - temp_avg_cumul += temp; - temp_avg_count += 1; - } - temperatures[1] = 22; + for(int i=0; i<4; i++) { + if(sensor_active[i] && mcpadc_has_new_data(i)) { + temperatures[i] = calc_temp( mcpadc_get_data(i), i ); + temp_avg_cumul[i] += temperatures[i]; + temp_avg_count[i] += 1; + } + } } + SOFTTIMER(2,500){ - int32_t temp = temp_avg_cumul; - temp /= temp_avg_count; - temp_avg_count = 0; temp_avg_cumul = 0; - int32_t nV = (temp * 625); - int32_t mK = nV/39; + for(int i=0; i<4; i++) { + if(sensor_active[i]) { + int32_t temp = temp_avg_cumul[i]; + temp /= temp_avg_count[i]; + 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){ timertmp=timer1_acc; timertmp++; diff --git a/firmware/slavechip/main.h b/firmware/slavechip/main.h index 4544e03..3344c5c 100644 --- a/firmware/slavechip/main.h +++ b/firmware/slavechip/main.h @@ -14,11 +14,7 @@ #include "softtimer.h" #include "debug.h" -extern uint8_t foo; -extern uint16_t bar; extern uint16_t timertmp; extern uint16_t temperatures[]; -void baz(); - #endif //__MAIN_H diff --git a/firmware/slavechip/mcp_adc.c b/firmware/slavechip/mcp_adc.c index ed40489..1c6856a 100644 --- a/firmware/slavechip/mcp_adc.c +++ b/firmware/slavechip/mcp_adc.c @@ -42,8 +42,10 @@ void mcpadc_init(uint8_t 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 */ if(unread_data_available){ // 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 -int32_t mcpadc_get_data(void) +int32_t mcpadc_get_data(uint8_t channel) { + // TODO: implement channel if(!unread_data_available){ return 0; } @@ -86,7 +89,7 @@ int32_t mcpadc_get_data(void) return value; } #else -int16_t mcpadc_get_data(void) +int16_t mcpadc_get_data(uint8_t channel) { if(!unread_data_available){ return 0; diff --git a/firmware/slavechip/mcp_adc.h b/firmware/slavechip/mcp_adc.h index db90bcc..33cf987 100644 --- a/firmware/slavechip/mcp_adc.h +++ b/firmware/slavechip/mcp_adc.h @@ -26,15 +26,15 @@ void mcpadc_init(uint8_t mode); /* tests if the adc has a new sample * 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 * !! return type depends on defines */ #if ADC_ENABLE_18_BIT_MODE -int32_t mcpadc_get_data(void); +int32_t mcpadc_get_data(uint8_t channel); #else -int16_t mcpadc_get_data(void); +int16_t mcpadc_get_data(uint8_t channel); #endif /* instructs the adc to take a new sample now diff --git a/firmware/slavechip/muxer.c b/firmware/slavechip/muxer.c index 53fecd4..39c3a3d 100644 --- a/firmware/slavechip/muxer.c +++ b/firmware/slavechip/muxer.c @@ -14,3 +14,19 @@ void muxer_set(uint8_t channel){ //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<