#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include <LibPrintf.h>

#ifdef __cplusplus
extern "C" {
#endif

#define BAUD 115200

#include "ds18b20.h"
#include "print.h"
#include "uart.h"

#ifdef __cplusplus
}
#endif

int main(void)
{
    // Set up DS18B20
    volatile uint8_t* port = &PORTB;
    volatile uint8_t* direction = &DDRB;
    volatile uint8_t* portin = &PINB;

    uint8_t mask = (1 << PORTB2); // Set mask to pin B2

    // Change this to match your sensor's ROM address
    uint8_t rom[8] = {0x28, 0xFF, 0xB1, 0x84, 0x16, 0x04, 0x00, 0xB9};

    // Initialize serial communication
    if (uart_init(SERIAL_BAUD_RATE) != 0) {
        printf("Error: failed to initialize serial communication\n");
        return -1;
    }

    // Enable global interrupts
    sei();

    // Variables to hold temperature data and error
    int16_t temp = 0;
    uint8_t error = 0;

    // Initialize one-wire interface
    onewireInit(port, direction, portin, mask);

    // Read the ROM address of the DS18B20 sensor
    ds18b20rom(port, direction, portin, mask, rom);

    // Set the resolution of the DS18B20 sensor to 12 bits
    ds18b20wsp(port, direction, portin, mask, rom, 0x1F, 0x3F, DS18B20_RES12);

    while (1)
    {
        // Request temperature conversion
        error = ds18b20convert(port, direction, portin, mask, rom);

        if (error != DS18B20_ERROR_OK) {
            printf("Error: %d\n", error);
            continue;
        }

        // Wait for conversion to complete
        _delay_ms(750);

        // Read temperature with 12-bit resolution
        error = ds18b20read(port, direction, portin, mask, rom, &temp);

        if (error != DS18B20_ERROR_OK) {
            printf("Error: %d\n", error);
            continue;
        }

        // Print temperature to serial monitor
        printf("Temperature: %.3f C\n", (float)temp * 0.5);
    }

    return 0;
}