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|
|--------------------------------------------------------------------------------------------------------------------------|
| 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 |
|--------------------------------------------------------------------------------------------------------------------------|

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

@ -2,7 +2,7 @@ CFLAGS += -save-temps
CFLAGS += -std=gnu99 -Wall # implements C99, for <util/atomic.h>
# 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

@ -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;

@ -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

@ -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;

@ -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;

@ -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);

@ -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

@ -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++;

@ -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

@ -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;

@ -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

@ -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<<channel);
}
void offset_measure_stop(){
PORTD &= ~0x0f;
}

@ -4,3 +4,7 @@
void muxer_init();
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[] = {
&timertmp,
&temperatures[0],
&temperatures[1],
&temperatures[2],
&temperatures[3],
};
funptr_t spi_proto_funcs[] = {
&dbgHasNew,
&dbgAdvanceChar
};

Loading…
Cancel
Save