#include <string.h>
#include <util/crc16.h>
#include <util/delay.h>
#include "main.h"
#include "ds18b20.h"
#include "1wire.h"

union {
	signed int t;
	unsigned char owbuffer[9];
} t;

#define MAX_ERRORS 5

unsigned char rom_num;
unsigned char rom_tab[MAX_SENSOR_NUM][8];
unsigned char temp_ok;
signed int temps[MAX_SENSOR_NUM];

unsigned char find_1wire(void){
	unsigned char rom[8];
	unsigned char i=0, rv=0, j;
	unsigned char crc = 0;
	do {
		rv = _1WireSearch(rv, rom);
		memcpy(rom_tab[i], rom, 8);
		for(j=0;j<8;j++){
			crc = _crc_ibutton_update(crc, rom[j]);
		}
		if(crc) return 1;
		i++;
	} while(rv && i<MAX_SENSOR_NUM);
	rom_num = i;
	return 0;
}

void gettemp(void){
	unsigned char i, j, crc=0, tmp;
	static unsigned char error_cnt[MAX_SENSOR_NUM];
	signed int temp;
	unsigned char temp_ok_out = 0;

	if(timers.owire) return;

	_1WirePoweroff();
	_delay_ms(1);

	for(j=0; j<rom_num; j++){

		if(_1WireInit() != 1){
			rom_num = 0;
			break;
		}

		_1WireWriteByte(0x55);
		_1WireSendRom(rom_tab[j]);
		_1WireWriteByte(0xbe);

		for(i=0;i<9;i++){
			tmp = _1WireReadByte();
			t.owbuffer[i] = tmp;
			crc = _crc_ibutton_update(crc, tmp);
		}
		if(!crc){
			if(t.owbuffer[0] == 0x50 && t.owbuffer[1] == 0x05 && t.owbuffer[5] == 0xff && t.owbuffer[7] == 0x10) continue;

			temp = t.t;
			temp *= (int)(0.625*16);
			temp >>= 4;
			if(t.owbuffer[2] <= MAX_SENSOR_NUM){
				temps[t.owbuffer[2]] = temp;
				temp_ok_out |= 1<<t.owbuffer[2];
			}
		}
	}

	for(i=0; i<MAX_SENSOR_NUM; i++){
		if(!(temp_ok_out & (1<<i))){
			if(error_cnt[i] > MAX_ERRORS){
				temp_ok &= ~(1<<i);
			} else {
				error_cnt[i]++;
			}
		} else {
			error_cnt[i] = 0;
			temp_ok |= 1<<i;
		}
	}
	
	find_1wire();

	_1WireInit();
	_1WireWriteByte(0xcc);
	_1WireWriteBytePR(0x44);
	atomic_set_uint(&timers.owire, ms(4000));
}