/*
 * temperature.c
 *
 * Created: 09.12.2015 13:26:43
 *  Author: vasia
 */ 
#include <stdio.h>
#include <pio.h>
#include <asf.h>
#include "temperature.h"

#define IRQ_PRIOR_PIO    0


extern int DS18_pin_lv;





void THERM_LOW()
{
	pio_clear(P_TEMPERATURE, PIN_DS18);
}

void THERM_HIGH()
{
	pio_set(P_TEMPERATURE, PIN_DS18);
}

void THERM_OUTPUT_MODE()
{
	pio_set_output(P_TEMPERATURE, PIN_DS18, HIGH, DISABLE, ENABLE);
	THERM_HIGH();	
}

void THERM_INPUT_MODE()
{
	pio_set_input(P_TEMPERATURE, PIN_DS18, 0);//, PIO_PULLUP | PIO_DEGLITCH);
	//pio_set_debounce_filter(P_TEMPERATURE, PIN_DS18, 10);   // Âêëþ÷åíèå ôèëüòðà äðåáåçãà êîíòàêòîâ
	
}
uint8_t therm_reset()
{
	uint8_t i;
	//Pull line low and wait for 480uS
	THERM_OUTPUT_MODE();
	THERM_LOW();
	delay_us(480);
	//Release line and wait for 60uS
	THERM_INPUT_MODE();
	delay_us(60);
	//Store line value and wait until the completion of 480uS period
	i=pio_get_pin_value(PIN_DS18_IDX);
	delay_us(420);
	//Return the value read from the presence pulse (0=OK, 1=WRONG)
	return i;
}void therm_write_bit(uint8_t bit){
	//Pull line low for 1uS
	THERM_OUTPUT_MODE();
	THERM_LOW();
	delay_us(1);
	//If we want to write 1, release the line (if not will keep low)
	if(bit) THERM_INPUT_MODE();
	//Wait for 60uS and release the line
	delay_us(60);
	THERM_INPUT_MODE();
}

void therm_write_byte(uint8_t byte)
{
	uint8_t i=8;
	while(i--)
	{
		//Write actual bit and shift one position right to make
		//the next bit ready
		therm_write_bit(byte&1);
		byte>>=1;
	}
}

uint8_t therm_read_bit(void){
	uint8_t bit=0;
	//Pull line low for 1uS
	THERM_OUTPUT_MODE();
	THERM_LOW();
	delay_us(1);
	//Release line and wait for 14uS
	THERM_INPUT_MODE();
	delay_us(5);
	//Read line value
	if(pio_get_pin_value(PIN_DS18_IDX)) bit=1;
	//Wait for 45uS to end and return read value
	delay_us(54);
	return bit;
}
uint8_t therm_read_byte(void){
	uint8_t i=8, n=0;
	while(i--)
	{
		//Shift one position right and store read value
		n>>=1;
		n|=(therm_read_bit()<<7);
	}
	return n;
}

int therm_read_temperature(char *buffer){
	// Buffer length must be at least 12bytes long! ["+XXX.XXXX C"]
	uint8_t temperature[2];
	int8_t digit;
	uint16_t decimal;
	//Reset, skip ROM and start temperature conversion
	if (therm_reset() !=0)
		return ERROR_INIT;		
	therm_write_byte(THERM_CMD_SKIPROM);
	therm_write_byte(THERM_CMD_CONVERTTEMP);
	//Wait until conversion is complete
	//while(!therm_read_bit())
	while(!pio_get_pin_value(PIN_DS18_IDX))
		;
	//Reset, skip ROM and send command to read Scratchpad
	if (therm_reset() !=0)
	{
		return ERROR_INIT;
	}
	therm_write_byte(THERM_CMD_SKIPROM);
	therm_write_byte(THERM_CMD_RSCRATCHPAD);
	//Read Scratchpad (only 2 first bytes)
	temperature[0]=therm_read_byte();
	temperature[1]=therm_read_byte();
	therm_reset();
	//Store temperature integer digits and decimal digits
	digit=temperature[0]>>4;
	digit|=(temperature[1]&0x7)<<4;
	//Store decimal digits
	decimal=temperature[0]&0xf;
	decimal*=THERM_DECIMAL_STEPS_12BIT;
	//Format temperature into a string [+XXX.XXXX C]
	sprintf(buffer, "%+d.%u", digit, decimal/100);
	return 0;
}